Skip to main content

Crate wire_codec

Crate wire_codec 

Source
Expand description

§wire-codec

A runtime-agnostic toolkit for binary framing and codec composition.

wire-codec provides the primitives you need to build a binary protocol: zero-copy buffer cursors, variable-length integer codecs, bit-level cursors, bit-packed structs, checksums, byte stuffing, and frame extraction strategies. Its core allocates nothing on the encode or decode path (only the optional codec adapters grow a bytes::BytesMut), it has no required runtime dependencies, and compiles on no_std targets when the default std feature is disabled.

§When to reach for this crate

Pick wire-codec when you need to:

  • Implement a custom binary protocol over any transport that delivers contiguous byte slices (TCP, UDP, in-memory queue, shared memory, serial link).
  • Frame a byte stream into discrete messages using a fixed-width or varint length prefix, or a delimiter, with a bounded payload size and linear-time streaming.
  • Encode and decode integers compactly via LEB128 varint and zigzag.
  • Pack fields into a record with bit-level precision, by hand with BitWriter / BitReader or declaratively with packed_struct!.
  • Add an integrity check (CRC-16, CRC-32, CRC-32C) to every frame, or COBS-stuff payloads for a serial link.

You probably want a higher-level serialization crate (serde, prost, bincode) if you need schema evolution or introspection. This crate is the layer underneath.

§Module map

ModuleProvides
bufReadBuf and WriteBuf, the zero-copy byte cursors every other module is built on.
errorError and Result, the crate-wide error contract.
traitsEncode and Decode, the codec trait pair, with impls for primitives, arrays, tuples, and the Be / Le / Varint wrappers.
varintLEB128 varint for u16, u32, u64, usize, and zigzag i32 / i64, with canonical (strict) decoders.
zigzagSigned-to-unsigned mapping for compact signed varints.
bitfieldBitReader and BitWriter for MSB-first packed bits.
packedpacked_struct! and the PackedField trait for bit-packed structs.
framingThe Framer trait, StreamDecoder, and the LengthPrefixed, VarintPrefixed, Delimited, and Checksummed strategies.
checksumThe Checksum trait and CRC-16/CCITT-FALSE, CRC-32, CRC-32C.
cobsConsistent Overhead Byte Stuffing.
codecFrameCodec, a bytes::BytesMut adapter with tokio-util and asynchronous-codec trait impls (optional features).

§Example

Length-prefix a payload, then read it back:

use wire_codec::WriteBuf;
use wire_codec::framing::{Endian, Framer, LengthPrefixed, LengthWidth};

let framer = LengthPrefixed::bounded(LengthWidth::U16, Endian::Big);

let mut out = [0u8; 32];
let mut buf = WriteBuf::new(&mut out);
framer.write_frame(b"ping", &mut buf).unwrap();
let n = buf.position();

let frame = framer.next_frame(&out[..n]).unwrap().unwrap();
assert_eq!(frame.payload(), b"ping");

§Error contract

Every fallible operation returns Result and leaves the cursor it was given at its original position on error. The crate’s own writers (WriteBuf methods, varint encoders, every built-in framer’s write_frame, cobs, and packed_struct! encoding) also check room and validity before writing, so on error nothing past the cursor is modified either. Composites that run other code can still leave bytes behind the restored cursor: a tuple whose later element fails for a reason other than lack of room, and Checksummed around a custom framer that reports no max_frame_len.

Malformed or hostile input never causes a panic, including on 32-bit targets, where every length taken from the wire is converted with checked arithmetic. The only runtime assertion reachable through the public API is a debug_assert! in Frame::new that catches a custom framer reporting fewer consumed bytes than its payload. The other assertions are internal invariant checks (debug_assert!s in crate-private cursor helpers) and compile-time checks (the checksum width in Checksummed::new and the field widths in packed_struct!).

§Stability

From 1.0.0 onward, the public API is frozen. Subsequent 1.x releases add only bug fixes, performance improvements, and non-breaking additions:

Any breaking change requires a 2.0 release.

The minimum supported Rust version (MSRV) is 1.85. Raising it is not treated as a breaking change: it happens only in a minor release, is called out in the changelog, and is never done in a patch release.

§Feature flags

FeatureDefaultEffect
stdyesLinks the standard library and adds From<Error> for std::io::Error. Drop it for no_std targets; Error implements core::error::Error either way.
memchrnoDelimiter search through the memchr crate (SIMD, linear-time multi-byte search) instead of the built-in SWAR scan.
bytesnoThe codec module: FrameCodec over bytes::BytesMut. Works without std.
tokio-utilnotokio_util::codec::{Decoder, Encoder} for FrameCodec. Implies bytes and std.
asynchronous-codecnoasynchronous_codec::{Decoder, Encoder} for FrameCodec. Implies bytes and std.

§License

Dual-licensed under Apache-2.0 OR MIT.

Re-exports§

pub use bitfield::BitReader;
pub use bitfield::BitWriter;
pub use buf::ReadBuf;
pub use buf::WriteBuf;
pub use error::Error;
pub use error::Result;
pub use traits::Be;
pub use traits::Decode;
pub use traits::Encode;
pub use traits::Le;
pub use traits::Varint;

Modules§

bitfield
Bit-level read and write cursors.
buf
Zero-copy cursor primitives over borrowed byte slices.
checksum
Frame checksums.
cobs
Consistent Overhead Byte Stuffing (COBS).
codecbytes
Adapters that run a Framer over a growable bytes::BytesMut buffer.
error
Error type returned by codec and framing operations.
framing
Frame extraction strategies.
packed
Packed struct encoding.
traits
Core traits implemented by every encodable value.
varint
Unsigned LEB128 varint encoding, plus zigzag-mapped signed helpers.
zigzag
Zigzag encoding for signed integers.

Macros§

packed_struct
Declare a bit-packed struct and implement Encode and Decode for it.

Constants§

VERSION
Crate version string, populated by Cargo at build time.