# v0.5.0 - Hardened Implementation
`wire-codec` 0.5.0 turns the 0.2.0 foundation into a battle-tested
implementation. The public API is unchanged; the work in this release is
about evidence.
Every codec primitive, every framer, and every buffer cursor is now backed
by property tests that exercise the full state space, integration tests
that compose the pieces against realistic protocol shapes, runnable
examples that double as documentation, and a dependency-free benchmark
harness that reports per-operation nanoseconds.
## Highlights
- **Property tests.** Six `proptest` files (`tests/prop_*.rs`) verify
invariants across the codec surface:
- Varint: round-trip for every `u32` / `u64`, size agreement between
`encoded_len` and `encode`, truncation always yields
`UnexpectedEof`, overlong input always yields `VarintOverflow`,
arbitrary byte slices never panic the decoder.
- Zigzag: round-trip in both directions for `i32` / `i64` and
`u32` / `u64`, plus the small-magnitude invariant that justifies its
existence.
- Framing: encode-then-decode is the identity across every `LengthWidth`
and `Endian` combination; truncated wire input always returns
`Ok(None)`; oversized payloads always yield `FrameTooLarge`; random
bytes never panic either framer.
- Bitfield: arbitrary sequences of `(value, width)` writes round-trip,
`BitWriter::finish` reports the correct byte count, value-overflow
detection fires on any value with bits set above the requested width.
- **Integration tests.** A new `tests/integration_protocols.rs` covers
protocol shapes a downstream user would actually build:
- Length-prefixed message streams with partial delivery (the framer
re-reads correctly as bytes arrive in arbitrary chunks).
- Newline-delimited text command protocols.
- HTTP-style CR/LF request line + header + empty-line + body parsing.
- Two-layer protocols (length-prefixed frame containing a varint /
zigzag record).
- Back-pressure: every prefix below a complete frame returns `Ok(None)`
without consuming bytes.
- **Examples.** Three runnable demos under `examples/`:
- `length_prefixed_echo` — encode and decode a small message batch.
- `newline_protocol` — parse a newline-delimited transcript including a
partial trailing frame.
- `varint_record` — show the varint / zigzag combination used for
compact signed deltas.
- **Benchmarks.** Two dependency-free harnesses in `benches/`:
- `codec.rs` — varint encode / decode (u32 and u64), zigzag, and
`ReadBuf` / `WriteBuf` primitives.
- `framing.rs` — length-prefixed write and read, delimited scan for
both short and long inputs.
Local numbers on the development machine (release profile, single
thread, Windows 11):
| Operation | ns/op |
| ----------------------------------------------- | ------- |
| `varint::encode_u32` (value 300) | ~0.4 |
| `varint::encode_u32` (`u32::MAX`) | ~0.7 |
| `varint::decode_u32` (2 bytes) | ~0.2 |
| `varint::decode_u32` (5 bytes) | ~0.2 |
| `varint::encode_u64` (`u64::MAX`) | ~1.1 |
| `varint::decode_u64` (10 bytes) | ~1.8 |
| `zigzag::encode_i32` (-1) | ~0.4 |
| `LengthPrefixed::write_frame` (64 B) | ~1.6 |
| `LengthPrefixed::next_frame` (64 B) | ~2.0 |
| `Delimited::next_frame` (short line) | ~2.4 |
| `Delimited::next_frame` (1 KiB scan + CRLF) | ~1314 |
Numbers will vary by machine. They are committed as a baseline rather
than a target; the linear `Delimited` scan is the obvious candidate for
future SIMD acceleration.
## What did not change
- The public API surface from 0.2.0 is unchanged. Every type, trait, and
function signature is preserved. Code that compiled against 0.2.0 will
compile against 0.5.0 without modification.
- Edition stays at `2021`. MSRV stays at `1.75`. License stays
Apache-2.0 OR MIT. Zero runtime dependencies.
## Dev-dependency footprint
`proptest` was added as a dev-only dependency for property testing,
pinned to `>=1, <1.6` so the `cargo test` build resolves on MSRV 1.75.
The crate itself, when consumed downstream, still pulls in nothing.
The bench harness is a manual `std::time::Instant` loop with
`std::hint::black_box` markers, intentionally without `criterion`.
This keeps the bench build MSRV-compatible and dependency-free.
## CI and tooling
- `actions/cache@v5` (was v4) to retire the Node 20 deprecation
warning on GitHub Actions runners.
- `.gitattributes` now pins all text files to LF on checkout, so Windows
runners produce the same line endings as `rustfmt.toml` expects.
- `clippy.toml` only declares options that exist on MSRV 1.75
(`allow-unwrap-in-tests`, `allow-expect-in-tests`).
- `varint::encoded_len_*` carry
`#[allow(unknown_lints, clippy::manual_div_ceil)]` so the manual
ceiling-divide expression compiles cleanly on every clippy version in
the supported range.
## Verification
This release was built and tested green under the directives matrix:
- `cargo build` (default features)
- `cargo build --no-default-features`
- `cargo build --all-features`
- `cargo +1.75 build --all-features --tests`
- `cargo +1.75 test --all-features`
- `cargo fmt --all -- --check`
- `cargo clippy --all-targets --all-features -- -D warnings`
- `cargo +1.75 clippy --all-targets --all-features -- -D warnings`
- `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features`
- `cargo bench --bench codec`
- `cargo bench --bench framing`
Test totals: 25 unit + 5 integration + 6 + 5 + 6 + 3 property + 3 smoke +
18 doctests = **71 tests** across stable and MSRV.
## Compatibility
- Edition: `2021`
- MSRV: Rust `1.75`
- License: Apache-2.0 OR MIT
- Platforms: Linux, macOS, Windows (CI on all three, stable + 1.75)
- Runtime dependencies: none
- Dev dependencies: `proptest` (test-only)
## What is next
Phase 0.9.0 (Hardening + Audit) per `.dev/ROADMAP.md`. That phase is a
feature freeze and a one-shot quality audit:
- Sealed traits where appropriate, `#[non_exhaustive]` on growth-likely
enums (already in place for `Error`; revisit `LengthWidth`).
- Per-variant error documentation and per-error-path test coverage.
- Allocation profile of the hot paths checked.
- Audit checklist in `.dev/ROADMAP.md` worked through.
- Audit findings logged in `docs/release/v0.9.0.md`.
After 0.9.x audit fixes, 1.0.0 is the stable freeze.