refactor(cli): move compression status classification to Rust

Move the aggregate compression-result classification out of the C wrapper and into the Rust fileio module. Keep C responsible for the user-facing EXM_THROW diagnostics and the existing fallback assertion, so optional-format build guards and command-line behavior remain unchanged. The Rust classifier also makes unexpected statuses explicit without widening the format callback 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; GCC and Clang syntax-only checks; make -j1 -C tests test (all 41 shell tests, fuzzer, zstd tester, and zstream tester passed).
This commit is contained in:
2026-07-20 17:59:38 +02:00
parent 0bd25053b7
commit bfd61e6ed7
2 changed files with 72 additions and 6 deletions
+19 -6
View File
@@ -1070,6 +1070,17 @@ enum {
FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED = 4
};
enum {
FIO_RUST_COMPRESS_DIAGNOSTIC_OK = 0,
FIO_RUST_COMPRESS_DIAGNOSTIC_GZIP_UNSUPPORTED = 1,
FIO_RUST_COMPRESS_DIAGNOSTIC_LZMA_UNSUPPORTED = 2,
FIO_RUST_COMPRESS_DIAGNOSTIC_LZ4_UNSUPPORTED = 3,
FIO_RUST_COMPRESS_DIAGNOSTIC_ZSTD_UNSUPPORTED = 4,
FIO_RUST_COMPRESS_DIAGNOSTIC_UNKNOWN = 5
};
int FIO_rust_compressFilenameDiagnostic(int status);
typedef unsigned long long (*FIO_rust_compress_zstd_fn)(
void* fCtx, void* prefs, void* ress,
const char* srcFileName, U64 srcFileSize,
@@ -3005,6 +3016,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
U64 const fileSize = UTIL_getFileSize(srcFileName);
FIO_rust_compress_callbacks_t callbacks;
int status;
int diagnostic;
memset(&callbacks, 0, sizeof(callbacks));
callbacks.opaque = &displayCtx;
@@ -3025,19 +3037,20 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
fCtx, prefs, &ress, dstFileName, srcFileName, fileSize,
compressionLevel, &callbacks);
switch (status) {
case FIO_RUST_COMPRESS_OK:
diagnostic = FIO_rust_compressFilenameDiagnostic(status);
switch (diagnostic) {
case FIO_RUST_COMPRESS_DIAGNOSTIC_OK:
return 0;
case FIO_RUST_COMPRESS_GZIP_UNSUPPORTED:
case FIO_RUST_COMPRESS_DIAGNOSTIC_GZIP_UNSUPPORTED:
EXM_THROW(20, "zstd: %s: file cannot be compressed as gzip (zstd compiled without ZSTD_GZCOMPRESS) -- ignored \n",
srcFileName);
case FIO_RUST_COMPRESS_LZMA_UNSUPPORTED:
case FIO_RUST_COMPRESS_DIAGNOSTIC_LZMA_UNSUPPORTED:
EXM_THROW(20, "zstd: %s: file cannot be compressed as xz/lzma (zstd compiled without ZSTD_LZMACOMPRESS) -- ignored \n",
srcFileName);
case FIO_RUST_COMPRESS_LZ4_UNSUPPORTED:
case FIO_RUST_COMPRESS_DIAGNOSTIC_LZ4_UNSUPPORTED:
EXM_THROW(20, "zstd: %s: file cannot be compressed as lz4 (zstd compiled without ZSTD_LZ4COMPRESS) -- ignored \n",
srcFileName);
case FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED:
case FIO_RUST_COMPRESS_DIAGNOSTIC_ZSTD_UNSUPPORTED:
default:
assert(status == FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED);
EXM_THROW(20, "zstd: %s: file cannot be compressed as zstd -- ignored \n",
+53
View File
@@ -250,6 +250,27 @@ pub const FIO_RUST_COMPRESS_LZMA_UNSUPPORTED: c_int = 2;
pub const FIO_RUST_COMPRESS_LZ4_UNSUPPORTED: c_int = 3;
pub const FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED: c_int = 4;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_OK: c_int = 0;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_GZIP_UNSUPPORTED: c_int = 1;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_LZMA_UNSUPPORTED: c_int = 2;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_LZ4_UNSUPPORTED: c_int = 3;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_ZSTD_UNSUPPORTED: c_int = 4;
pub const FIO_RUST_COMPRESS_DIAGNOSTIC_UNKNOWN: c_int = 5;
/// Classifies the aggregate compression-selector result while leaving the
/// format-specific exception text and fallback assertion in C.
#[no_mangle]
pub extern "C" fn FIO_rust_compressFilenameDiagnostic(status: c_int) -> c_int {
match status {
FIO_RUST_COMPRESS_OK => FIO_RUST_COMPRESS_DIAGNOSTIC_OK,
FIO_RUST_COMPRESS_GZIP_UNSUPPORTED => FIO_RUST_COMPRESS_DIAGNOSTIC_GZIP_UNSUPPORTED,
FIO_RUST_COMPRESS_LZMA_UNSUPPORTED => FIO_RUST_COMPRESS_DIAGNOSTIC_LZMA_UNSUPPORTED,
FIO_RUST_COMPRESS_LZ4_UNSUPPORTED => FIO_RUST_COMPRESS_DIAGNOSTIC_LZ4_UNSUPPORTED,
FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED => FIO_RUST_COMPRESS_DIAGNOSTIC_ZSTD_UNSUPPORTED,
_ => FIO_RUST_COMPRESS_DIAGNOSTIC_UNKNOWN,
}
}
const FIO_ZSTD_COMPRESSION: c_int = 0;
const FIO_GZIP_COMPRESSION: c_int = 1;
const FIO_XZ_COMPRESSION: c_int = 2;
@@ -5438,6 +5459,38 @@ mod tests {
}
}
#[test]
fn aggregate_compression_status_diagnostic_preserves_format_mapping() {
for (status, diagnostic) in [
(FIO_RUST_COMPRESS_OK, FIO_RUST_COMPRESS_DIAGNOSTIC_OK),
(
FIO_RUST_COMPRESS_GZIP_UNSUPPORTED,
FIO_RUST_COMPRESS_DIAGNOSTIC_GZIP_UNSUPPORTED,
),
(
FIO_RUST_COMPRESS_LZMA_UNSUPPORTED,
FIO_RUST_COMPRESS_DIAGNOSTIC_LZMA_UNSUPPORTED,
),
(
FIO_RUST_COMPRESS_LZ4_UNSUPPORTED,
FIO_RUST_COMPRESS_DIAGNOSTIC_LZ4_UNSUPPORTED,
),
(
FIO_RUST_COMPRESS_ZSTD_UNSUPPORTED,
FIO_RUST_COMPRESS_DIAGNOSTIC_ZSTD_UNSUPPORTED,
),
] {
assert_eq!(FIO_rust_compressFilenameDiagnostic(status), diagnostic);
}
for status in [-1, 99] {
assert_eq!(
FIO_rust_compressFilenameDiagnostic(status),
FIO_RUST_COMPRESS_DIAGNOSTIC_UNKNOWN
);
}
}
const SOURCE_POLICY_STAT: u8 = 1;
const SOURCE_POLICY_EXCLUDED: u8 = 2;
const SOURCE_POLICY_OPEN: u8 = 3;