docs(rust): refresh migration boundary

Update the Rust rewrite documentation to match the current implementation
boundary.  The legacy decoder set is complete, and Rust now owns several
CLI file-I/O policy and resource leaves while C retains format dispatch,
metadata, and remaining orchestration.  Keep the stated boundary explicit so
passing hybrid tests do not imply that the full rewrite is finished.

Test Plan:
- git diff --cached --check
This commit is contained in:
2026-07-18 18:56:29 +02:00
parent 22bebab928
commit 428dfbc4f5
2 changed files with 27 additions and 24 deletions
+20 -19
View File
@@ -66,8 +66,9 @@ zstd ABI:
- `zstd_ddict` owns, loads, copies, and references decode dictionaries.
- Legacy decoding
- `legacy` hosts one frozen module per historical format; `legacy::zstd_v01`
ports the self-contained v0.1 decoder. Versions v0.2 through v0.7 are
still C.
through `legacy::zstd_v07` port the seven self-contained historical
decoders. Their original C translation units remain declaration-only
shims for the native build.
- Block decompression
- `zstd_decompress_block` decodes literal and sequence sections, maintains
FSE/Huffman repeat state, and executes compressed-block sequences.
@@ -78,8 +79,10 @@ zstd ABI:
- `zstd_cli` owns the Rust parser, safety policy, and dispatch. It is built
by the separate `cli/` static-library package only for program archives,
so library builds do not acquire program-only dependencies. The C
`fileio` backend still owns file opening, safe replacement, sparse writes,
metadata, and streaming I/O.
`fileio` layer still owns format-specific dispatch, metadata, and the
remaining C streaming/orchestration paths. Rust already owns the file
preference policy, filename decisions, source/destination opening,
dictionary buffers, asynchronous I/O pools, and pass-through copy leaf.
- `timefn` provides the monotonic nanosecond clock behind `UTIL_time_t`,
and `benchfn` owns the benchmark run/timing loop (`BMK_benchFunction`,
`BMK_benchTimedFn`) used by the CLI benchmark mode and by C test tools.
@@ -90,12 +93,12 @@ zstd ABI:
orchestration and reporting (`benchzstd.c`) remain C, reached from the
Rust parser through the `ZSTD_NOBENCH`-gated bridge in `zstdcli.c`.
The optimal block matcher, high-level frame compression, dictionary-building
except suffix-array construction, the legacy v0.2-v0.7 decoders, benchmark
orchestration (`benchzstd`), and the CLI file-I/O backend are still C. They
must move before the rewrite is complete. Keeping that boundary explicit
prevents a passing hybrid build from being mistaken for the final all-Rust
result.
The optimal block matcher, most high-level frame-compression orchestration,
dictionary-building except suffix-array construction, benchmark orchestration
and reporting (`benchzstd`), and several format-specific CLI I/O paths are
still C. They must move before the rewrite is complete. Keeping that boundary
explicit prevents a passing hybrid build from being mistaken for the final
all-Rust result.
## Legacy decoding
@@ -108,8 +111,8 @@ byte-identical to the original C files. Their only shared dependency is the
`errors` module, matching the C files' `error_private.h` include.
Cargo features `legacy-v01` .. `legacy-v07` gate the per-version modules and
are never default features. The build systems derive the feature list from
the C configuration:
are never default features. All seven modules are now available; the build
systems derive the enabled feature list from the C configuration:
- `lib/Makefile` and `programs/Makefile` map `ZSTD_LEGACY_SUPPORT=N` to the
features for versions >= N (0 disables legacy), matching the
@@ -125,13 +128,11 @@ directory name (for example `c1-d1-default-legacy5`), for the same reason the
HUF mode is encoded there: a cached archive built for one configuration must
never be linked into a build that expects another.
A feature whose version has not been ported yet gates nothing; the original
C file still provides that decoder, so mixed C/Rust legacy levels link
cleanly. Porting a version means adding `src/legacy/zstd_v0N.rs`, registering
it in `src/legacy/mod.rs` behind its feature, and reducing
`lib/legacy/zstd_v0N.c` to a declaration-only shim. For v0.1 the streaming
`ZSTDv01_Dctx` state lives entirely in Rust: C code only ever holds an opaque
pointer, so the C-side struct definition is gone.
Each port adds `src/legacy/zstd_v0N.rs`, registers it in `src/legacy/mod.rs`
behind its feature, and reduces `lib/legacy/zstd_v0N.c` to a
declaration-only shim. For v0.1 the streaming `ZSTDv01_Dctx` state lives
entirely in Rust: C code only ever holds an opaque pointer, so the C-side
struct definition is gone.
## Compatibility boundary
+7 -5
View File
@@ -4,11 +4,13 @@
//! Rust command-line frontend for zstd.
//!
//! This is intentionally a parser and dispatch layer, not a second file I/O
//! implementation. It reuses the mature C `fileio` layer through its narrow
//! public-in-the-programs-tree ABI: file opening, safe replacement, sparse
//! writes, dictionary loading, streaming, and metadata preservation remain in
//! `programs/fileio.c` for this first migration step.
//! This is the Rust parser and dispatch layer plus selected file-I/O leaves,
//! not yet a fully independent file-I/O implementation. It shares the
//! mature C `fileio` layer through a narrow public-in-the-programs-tree ABI:
//! Rust owns preference policy, filename decisions, file opening, dictionary
//! loading, asynchronous pools, and pass-through copying, while C still owns
//! format-specific dispatch, metadata preservation, and remaining streaming
//! orchestration.
//!
//! Benchmark mode (`-b`) parses and dispatches through the Rust CLI archive.
//! The bridge preserves the C CLI's argument normalization and uses the