refactor(cli): make decompression finish policy explicit in Rust
Extract the mixed-format decompression finish status mapping into a pure Rust policy helper and keep the existing callback side effects, diagnostics, and return values in the ABI wrapper. The explicit enum makes the success, pass-through, report, and impossible-status branches auditable and testable without widening the private fileio boundary. Test Plan: ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check; make -j1; ./tests/rustLibSmoke; make -j1 -C tests test (all shell tests, large streaming tests, native tester, fuzzer phases, and zstream tester passed).
This commit is contained in:
+86
-13
@@ -5218,6 +5218,31 @@ pub unsafe extern "C" fn FIO_rust_decompressFrames(
|
||||
/// successful-file finalization. C keeps the diagnostic and accounting
|
||||
/// callbacks because they touch `DISPLAY*` state and the private `FIO_ctx_t`
|
||||
/// layout; Rust owns the result policy and decides which callback is legal.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum DecompressFinishAction {
|
||||
Finish,
|
||||
PassThrough,
|
||||
ReportStatus,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
fn classify_decompress_finish_status(status: c_int) -> DecompressFinishAction {
|
||||
match status {
|
||||
FIO_RUST_DECOMPRESS_OK => DecompressFinishAction::Finish,
|
||||
FIO_RUST_DECOMPRESS_PASS_THROUGH => DecompressFinishAction::PassThrough,
|
||||
FIO_RUST_DECOMPRESS_EMPTY_INPUT
|
||||
| FIO_RUST_DECOMPRESS_SHORT_INPUT
|
||||
| FIO_RUST_DECOMPRESS_GZIP_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_LZMA_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_LZ4_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_FRAME_ERROR
|
||||
| FIO_RUST_DECOMPRESS_UNSUPPORTED_FORMAT
|
||||
| FIO_RUST_DECOMPRESS_PASS_THROUGH_ERROR
|
||||
| FIO_RUST_DECOMPRESS_ZSTD_UNSUPPORTED => DecompressFinishAction::ReportStatus,
|
||||
_ => DecompressFinishAction::Invalid,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn FIO_rust_finishDecompressFrames(
|
||||
status: c_int,
|
||||
@@ -5229,29 +5254,21 @@ pub unsafe extern "C" fn FIO_rust_finishDecompressFrames(
|
||||
assert!(!callbacks.is_null());
|
||||
|
||||
let callbacks = unsafe { &*callbacks };
|
||||
match status {
|
||||
FIO_RUST_DECOMPRESS_OK => {
|
||||
match classify_decompress_finish_status(status) {
|
||||
DecompressFinishAction::Finish => {
|
||||
if let Some(finish) = callbacks.finish {
|
||||
unsafe { finish(callbacks.opaque, src_file_name, decoded_size) };
|
||||
}
|
||||
0
|
||||
}
|
||||
FIO_RUST_DECOMPRESS_PASS_THROUGH => 0,
|
||||
FIO_RUST_DECOMPRESS_EMPTY_INPUT
|
||||
| FIO_RUST_DECOMPRESS_SHORT_INPUT
|
||||
| FIO_RUST_DECOMPRESS_GZIP_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_LZMA_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_LZ4_UNSUPPORTED
|
||||
| FIO_RUST_DECOMPRESS_FRAME_ERROR
|
||||
| FIO_RUST_DECOMPRESS_UNSUPPORTED_FORMAT
|
||||
| FIO_RUST_DECOMPRESS_PASS_THROUGH_ERROR
|
||||
| FIO_RUST_DECOMPRESS_ZSTD_UNSUPPORTED => {
|
||||
DecompressFinishAction::PassThrough => 0,
|
||||
DecompressFinishAction::ReportStatus => {
|
||||
if let Some(report_status) = callbacks.report_status {
|
||||
unsafe { report_status(callbacks.opaque, status, src_file_name) };
|
||||
}
|
||||
1
|
||||
}
|
||||
_ => {
|
||||
DecompressFinishAction::Invalid => {
|
||||
unreachable!("unknown Rust decompression status: {status}");
|
||||
}
|
||||
}
|
||||
@@ -9208,6 +9225,62 @@ mod tests {
|
||||
state.finished_sizes.push(decoded_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classifies_decompression_finish_statuses() {
|
||||
for (status, expected_action) in [
|
||||
(FIO_RUST_DECOMPRESS_OK, DecompressFinishAction::Finish),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_PASS_THROUGH,
|
||||
DecompressFinishAction::PassThrough,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_EMPTY_INPUT,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_SHORT_INPUT,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_GZIP_UNSUPPORTED,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_LZMA_UNSUPPORTED,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_LZ4_UNSUPPORTED,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_FRAME_ERROR,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_UNSUPPORTED_FORMAT,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_PASS_THROUGH_ERROR,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
(
|
||||
FIO_RUST_DECOMPRESS_ZSTD_UNSUPPORTED,
|
||||
DecompressFinishAction::ReportStatus,
|
||||
),
|
||||
] {
|
||||
assert_eq!(classify_decompress_finish_status(status), expected_action);
|
||||
}
|
||||
|
||||
for status in [-1, 99] {
|
||||
assert_eq!(
|
||||
classify_decompress_finish_status(status),
|
||||
DecompressFinishAction::Invalid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maps_decompression_status_and_finishes_only_success() {
|
||||
let mut state = DecompressResultState {
|
||||
|
||||
Reference in New Issue
Block a user