refactor(cli): move zstd frame action policy to Rust
Project the zstd frame decoder status into a Rust action classification while preserving C-owned diagnostics, error-help formatting, private resources, and exact decoding return values. Unknown statuses retain the assertion fallback and the existing frame-decoding error result. Test Plan: - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 ./tests/rustLibSmoke` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1 -C tests test` -- passed, including large streaming, native, fuzzer, and zstream phases
This commit is contained in:
+23
-15
@@ -404,6 +404,13 @@ enum {
|
||||
FIO_RUST_ZSTD_FRAME_DECODING_ERROR = 1,
|
||||
FIO_RUST_ZSTD_FRAME_PREMATURE_END = 2,
|
||||
};
|
||||
enum {
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_OK = 0,
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_DECODING_ERROR = 1,
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_PREMATURE_END = 2,
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_INVALID = 3,
|
||||
};
|
||||
int FIO_rust_decompressZstdFrameAction(int status);
|
||||
typedef void (*FIO_rust_frame_progress_fn)(void* opaque,
|
||||
const char* srcFileName,
|
||||
U64 decodedSize);
|
||||
@@ -3786,23 +3793,24 @@ FIO_decompressZstdFrames(FIO_ctx_t* const fCtx, dRess_t* ress,
|
||||
fCtx, ress->dctx, ress->readCtx, ress->writeCtx, srcFileName,
|
||||
alreadyDecoded, &decodedSize, &zstdError,
|
||||
FIO_decompressZstdFrameProgress);
|
||||
int const action = FIO_rust_decompressZstdFrameAction(status);
|
||||
|
||||
if (status == FIO_RUST_ZSTD_FRAME_OK)
|
||||
return decodedSize;
|
||||
if (status == FIO_RUST_ZSTD_FRAME_DECODING_ERROR) {
|
||||
DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n",
|
||||
srcFileName, ZSTD_getErrorName(zstdError));
|
||||
FIO_zstdErrorHelp(prefs, ress, zstdError, srcFileName);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
switch (action) {
|
||||
case FIO_RUST_ZSTD_FRAME_ACTION_OK:
|
||||
return decodedSize;
|
||||
case FIO_RUST_ZSTD_FRAME_ACTION_DECODING_ERROR:
|
||||
DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n",
|
||||
srcFileName, ZSTD_getErrorName(zstdError));
|
||||
FIO_zstdErrorHelp(prefs, ress, zstdError, srcFileName);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
case FIO_RUST_ZSTD_FRAME_ACTION_PREMATURE_END:
|
||||
DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n",
|
||||
srcFileName);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
default:
|
||||
assert(0);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
}
|
||||
if (status == FIO_RUST_ZSTD_FRAME_PREMATURE_END) {
|
||||
DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n",
|
||||
srcFileName);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return FIO_ERROR_FRAME_DECODING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -348,6 +348,42 @@ const FIO_RUST_ZSTD_ERROR_HELP_WINDOW_GUIDANCE: c_int = 1;
|
||||
#[cfg(feature = "decompression")]
|
||||
const FIO_RUST_ZSTD_ERROR_HELP_UNSUPPORTED_WINDOW_LOG: c_int = 2;
|
||||
|
||||
#[cfg(feature = "decompression")]
|
||||
const FIO_RUST_ZSTD_FRAME_OK: c_int = 0;
|
||||
#[cfg(feature = "decompression")]
|
||||
const FIO_RUST_ZSTD_FRAME_DECODING_ERROR: c_int = 1;
|
||||
#[cfg(feature = "decompression")]
|
||||
const FIO_RUST_ZSTD_FRAME_PREMATURE_END: c_int = 2;
|
||||
|
||||
#[cfg(feature = "decompression")]
|
||||
pub const FIO_RUST_ZSTD_FRAME_ACTION_OK: c_int = 0;
|
||||
#[cfg(feature = "decompression")]
|
||||
pub const FIO_RUST_ZSTD_FRAME_ACTION_DECODING_ERROR: c_int = 1;
|
||||
#[cfg(feature = "decompression")]
|
||||
pub const FIO_RUST_ZSTD_FRAME_ACTION_PREMATURE_END: c_int = 2;
|
||||
#[cfg(feature = "decompression")]
|
||||
pub const FIO_RUST_ZSTD_FRAME_ACTION_INVALID: c_int = 3;
|
||||
|
||||
#[cfg(feature = "decompression")]
|
||||
#[inline]
|
||||
fn decompress_zstd_frame_action(status: c_int) -> c_int {
|
||||
match status {
|
||||
FIO_RUST_ZSTD_FRAME_OK => FIO_RUST_ZSTD_FRAME_ACTION_OK,
|
||||
FIO_RUST_ZSTD_FRAME_DECODING_ERROR => FIO_RUST_ZSTD_FRAME_ACTION_DECODING_ERROR,
|
||||
FIO_RUST_ZSTD_FRAME_PREMATURE_END => FIO_RUST_ZSTD_FRAME_ACTION_PREMATURE_END,
|
||||
_ => FIO_RUST_ZSTD_FRAME_ACTION_INVALID,
|
||||
}
|
||||
}
|
||||
|
||||
/// Classify a zstd-frame status without owning the CLI's diagnostics or
|
||||
/// private decompression resources. C keeps the exact messages, error-help
|
||||
/// call, and return values for each resulting action.
|
||||
#[cfg(feature = "decompression")]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn FIO_rust_decompressZstdFrameAction(status: c_int) -> c_int {
|
||||
decompress_zstd_frame_action(status)
|
||||
}
|
||||
|
||||
#[cfg(feature = "decompression")]
|
||||
type FIO_rust_zstdErrorHelpDisplayFn =
|
||||
unsafe extern "C" fn(*mut c_void, c_int, *const c_char, u64, c_uint, c_uint, c_uint);
|
||||
@@ -2460,6 +2496,37 @@ mod tests {
|
||||
use std::fs;
|
||||
use std::mem::{align_of, offset_of, size_of};
|
||||
|
||||
#[cfg(feature = "decompression")]
|
||||
#[test]
|
||||
fn decompress_zstd_frame_action_preserves_status_classes() {
|
||||
let cases = [
|
||||
(FIO_RUST_ZSTD_FRAME_OK, FIO_RUST_ZSTD_FRAME_ACTION_OK),
|
||||
(
|
||||
FIO_RUST_ZSTD_FRAME_DECODING_ERROR,
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_DECODING_ERROR,
|
||||
),
|
||||
(
|
||||
FIO_RUST_ZSTD_FRAME_PREMATURE_END,
|
||||
FIO_RUST_ZSTD_FRAME_ACTION_PREMATURE_END,
|
||||
),
|
||||
(-1, FIO_RUST_ZSTD_FRAME_ACTION_INVALID),
|
||||
(3, FIO_RUST_ZSTD_FRAME_ACTION_INVALID),
|
||||
];
|
||||
|
||||
for (status, expected_action) in cases {
|
||||
assert_eq!(
|
||||
decompress_zstd_frame_action(status),
|
||||
expected_action,
|
||||
"unexpected action for zstd frame status {status}"
|
||||
);
|
||||
assert_eq!(
|
||||
FIO_rust_decompressZstdFrameAction(status),
|
||||
expected_action,
|
||||
"export disagrees for zstd frame status {status}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_exclusion_preserves_case_sensitive_suffixes_and_null_policy() {
|
||||
let cases = [
|
||||
|
||||
Reference in New Issue
Block a user