feat(cli): move list formatting to Rust
Move the per-file and multi-file --list row formatters out of programs/fileio.c. C still owns filesystem access, frame analysis, private fileInfo_t storage, and exact status diagnostics; Rust now formats the rows into byte buffers and sends them through a synchronous output callback. This keeps filenames byte-preserving and prevents the private C record from crossing the ABI while preserving the original display thresholds, human-readable size policy, unavailable-content spacing, checksum order, and total-row behavior. Replace the old display callbacks with one size-delimited output callback shared by the single-file and multi-file projections. Add explicit Rust ABI layout checks, formatter fixtures for normal/unavailable/verbose/checksum/total output, and callback-order assertions for the policy boundary. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets (208 passed) - ulimit -v 41943040; make -j1 - ulimit -v 41943040; make -j1 -C tests test (all original tests completed successfully) - git diff --check
This commit is contained in:
+12
-96
@@ -5109,18 +5109,17 @@ typedef int (*FIO_listFileGetInfoFn)(void* opaque, const char* fileName,
|
||||
typedef void (*FIO_listFileDisplayStatusFn)(void* opaque, int action,
|
||||
const char* fileName,
|
||||
int displayLevel);
|
||||
typedef void (*FIO_listFileDisplayInfoFn)(void* opaque, const char* fileName,
|
||||
const fileInfo_t* info,
|
||||
int displayLevel);
|
||||
typedef void (*FIO_listFileWriteOutputFn)(void* opaque, const char* data,
|
||||
size_t size);
|
||||
|
||||
/* This callback state is a deliberate repr(C) bridge: filesystem access,
|
||||
* frame analysis, exact diagnostics, and row formatting stay in C while Rust
|
||||
* owns the per-file policy/order around them. */
|
||||
* frame analysis, and exact diagnostics stay in C while Rust owns row
|
||||
* formatting and the per-file policy/order around it. */
|
||||
typedef struct {
|
||||
void* opaque;
|
||||
FIO_listFileGetInfoFn getInfo;
|
||||
FIO_listFileDisplayStatusFn displayStatus;
|
||||
FIO_listFileDisplayInfoFn displayInfo;
|
||||
FIO_listFileWriteOutputFn writeOutput;
|
||||
} FIO_listFileCallbacks_t;
|
||||
|
||||
typedef char FIO_rust_list_file_callbacks_get_info_offset[
|
||||
@@ -5128,8 +5127,8 @@ typedef char FIO_rust_list_file_callbacks_get_info_offset[
|
||||
typedef char FIO_rust_list_file_callbacks_status_offset[
|
||||
(offsetof(FIO_listFileCallbacks_t, displayStatus)
|
||||
== sizeof(void*) + sizeof(FIO_listFileGetInfoFn)) ? 1 : -1];
|
||||
typedef char FIO_rust_list_file_callbacks_info_offset[
|
||||
(offsetof(FIO_listFileCallbacks_t, displayInfo)
|
||||
typedef char FIO_rust_list_file_callbacks_output_offset[
|
||||
(offsetof(FIO_listFileCallbacks_t, writeOutput)
|
||||
== sizeof(void*) + sizeof(FIO_listFileGetInfoFn)
|
||||
+ sizeof(FIO_listFileDisplayStatusFn)) ? 1 : -1];
|
||||
|
||||
@@ -5141,8 +5140,7 @@ typedef struct {
|
||||
void (*displayHeader)(void* opaque);
|
||||
int (*listFile)(void* opaque, const char* fileName, int displayLevel,
|
||||
FIO_listFileInfoProjection_t* info);
|
||||
void (*displayTotal)(void* opaque,
|
||||
const FIO_listFileInfoProjection_t* total);
|
||||
FIO_listFileWriteOutputFn writeOutput;
|
||||
} FIO_listMultipleFilesCallbacks_t;
|
||||
|
||||
int FIO_rust_listFile(const char* inputName, int displayLevel,
|
||||
@@ -5261,61 +5259,6 @@ getFileInfo(fileInfo_t* info, const char* srcFileName)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
displayInfo(const char* inFileName, const fileInfo_t* info, int displayLevel)
|
||||
{
|
||||
UTIL_HumanReadableSize_t const window_hrs = UTIL_makeHumanReadableSize(info->windowSize);
|
||||
UTIL_HumanReadableSize_t const compressed_hrs = UTIL_makeHumanReadableSize(info->compressedSize);
|
||||
UTIL_HumanReadableSize_t const decompressed_hrs = UTIL_makeHumanReadableSize(info->decompressedSize);
|
||||
double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/(double)info->compressedSize;
|
||||
const char* const checkString = (info->usesCheck ? "XXH64" : "None");
|
||||
if (displayLevel <= 2) {
|
||||
if (!info->decompUnavailable) {
|
||||
DISPLAYOUT("%6d %5d %6.*f%4s %8.*f%4s %5.3f %5s %s\n",
|
||||
info->numSkippableFrames + info->numActualFrames,
|
||||
info->numSkippableFrames,
|
||||
compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix,
|
||||
decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix,
|
||||
ratio, checkString, inFileName);
|
||||
} else {
|
||||
DISPLAYOUT("%6d %5d %6.*f%4s %5s %s\n",
|
||||
info->numSkippableFrames + info->numActualFrames,
|
||||
info->numSkippableFrames,
|
||||
compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix,
|
||||
checkString, inFileName);
|
||||
}
|
||||
} else {
|
||||
DISPLAYOUT("%s \n", inFileName);
|
||||
DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames);
|
||||
if (info->numSkippableFrames)
|
||||
DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames);
|
||||
DISPLAYOUT("DictID: %u\n", info->dictID);
|
||||
DISPLAYOUT("Window Size: %.*f%s (%llu B)\n",
|
||||
window_hrs.precision, window_hrs.value, window_hrs.suffix,
|
||||
(unsigned long long)info->windowSize);
|
||||
DISPLAYOUT("Compressed Size: %.*f%s (%llu B)\n",
|
||||
compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix,
|
||||
(unsigned long long)info->compressedSize);
|
||||
if (!info->decompUnavailable) {
|
||||
DISPLAYOUT("Decompressed Size: %.*f%s (%llu B)\n",
|
||||
decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix,
|
||||
(unsigned long long)info->decompressedSize);
|
||||
DISPLAYOUT("Ratio: %.4f\n", ratio);
|
||||
}
|
||||
|
||||
if (info->usesCheck && info->numActualFrames == 1) {
|
||||
DISPLAYOUT("Check: %s %02x%02x%02x%02x\n", checkString,
|
||||
info->checksum[3], info->checksum[2],
|
||||
info->checksum[1], info->checksum[0]
|
||||
);
|
||||
} else {
|
||||
DISPLAYOUT("Check: %s\n", checkString);
|
||||
}
|
||||
|
||||
DISPLAYOUT("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
FIO_listFileGetInfo(void* opaque, const char* inFileName, fileInfo_t* info)
|
||||
{
|
||||
@@ -5352,11 +5295,10 @@ FIO_listFileDisplayStatus(void* opaque, int action,
|
||||
}
|
||||
|
||||
static void
|
||||
FIO_listFileDisplayInfo(void* opaque, const char* inFileName,
|
||||
const fileInfo_t* info, int displayLevel)
|
||||
FIO_listFileWriteOutput(void* opaque, const char* data, size_t size)
|
||||
{
|
||||
(void)opaque;
|
||||
displayInfo(inFileName, info, displayLevel);
|
||||
(void)fwrite(data, 1, size, stdout);
|
||||
}
|
||||
|
||||
/* Rust owns this stateless --list input-name predicate. */
|
||||
@@ -5397,36 +5339,10 @@ FIO_listFileCallback(void* opaque, const char* fileName, int displayLevel,
|
||||
callbacks.opaque = NULL;
|
||||
callbacks.getInfo = FIO_listFileGetInfo;
|
||||
callbacks.displayStatus = FIO_listFileDisplayStatus;
|
||||
callbacks.displayInfo = FIO_listFileDisplayInfo;
|
||||
callbacks.writeOutput = FIO_listFileWriteOutput;
|
||||
return FIO_rust_listFile(fileName, displayLevel, info, &callbacks);
|
||||
}
|
||||
|
||||
static void
|
||||
FIO_listFileDisplayTotal(void* opaque,
|
||||
const FIO_listFileInfoProjection_t* total)
|
||||
{
|
||||
UTIL_HumanReadableSize_t const compressed_hrs = UTIL_makeHumanReadableSize(total->compressedSize);
|
||||
UTIL_HumanReadableSize_t const decompressed_hrs = UTIL_makeHumanReadableSize(total->decompressedSize);
|
||||
double const ratio = (total->compressedSize == 0) ? 0 : ((double)total->decompressedSize)/(double)total->compressedSize;
|
||||
const char* const checkString = (total->usesCheck ? "XXH64" : "");
|
||||
(void)opaque;
|
||||
DISPLAYOUT("----------------------------------------------------------------- \n");
|
||||
if (total->decompUnavailable) {
|
||||
DISPLAYOUT("%6d %5d %6.*f%4s %5s %u files\n",
|
||||
total->numSkippableFrames + total->numActualFrames,
|
||||
total->numSkippableFrames,
|
||||
compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix,
|
||||
checkString, (unsigned)total->nbFiles);
|
||||
} else {
|
||||
DISPLAYOUT("%6d %5d %6.*f%4s %8.*f%4s %5.3f %5s %u files\n",
|
||||
total->numSkippableFrames + total->numActualFrames,
|
||||
total->numSkippableFrames,
|
||||
compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix,
|
||||
decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix,
|
||||
ratio, checkString, (unsigned)total->nbFiles);
|
||||
}
|
||||
}
|
||||
|
||||
int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int displayLevel)
|
||||
{
|
||||
FIO_listMultipleFilesCallbacks_t callbacks;
|
||||
@@ -5436,7 +5352,7 @@ int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int dis
|
||||
callbacks.displayNoFilesError = FIO_listFileDisplayNoFilesError;
|
||||
callbacks.displayHeader = FIO_listFileDisplayHeader;
|
||||
callbacks.listFile = FIO_listFileCallback;
|
||||
callbacks.displayTotal = FIO_listFileDisplayTotal;
|
||||
callbacks.writeOutput = FIO_listFileWriteOutput;
|
||||
return FIO_rust_listMultipleFiles(numFiles, filenameTable, displayLevel, &callbacks);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user