Skip to main content

Module bitstream

Module bitstream 

Source
Expand description

A bit-level stream codec — read/write fields at arbitrary bit offsets, not just byte boundaries.

A byte-oriented Read + Seek codec can only address byte boundaries, so a field that starts mid-byte (a 108-bit DMR payload, a 48-bit sync pattern) forces hand-rolled backward seeks and nibble shifts. BitReader/BitWriter track a bit cursor over a byte buffer and read/write any Bits value (u1..u127, #[bitfield], #[derive(BitEnum)]) directly — bit-aware and fast (shift/mask, no bitvec).

The wire Layout is configurable: bit order (MSB-first default — bit 0 is the high bit of byte 0, the RFC/ETSI convention — or LSB-first) and byte order (big- endian default, or little-endian for byte-multiple values).

use bnb::{u4, u12, BitReader, BitWriter};

// Pack a 4-bit then a 12-bit field into a 16-bit (2-byte) stream.
let mut w = BitWriter::new();
w.write(u4::new(0xA)).unwrap();
w.write(u12::new(0xBCD)).unwrap();
let bytes = w.into_bytes();
assert_eq!(bytes, [0xAB, 0xCD]);

let mut r = BitReader::new(&bytes);
assert_eq!(r.read::<u4>().unwrap(), u4::new(0xA));
assert_eq!(r.read::<u12>().unwrap(), u12::new(0xBCD));

Structs§

BitBuf
A push/pull, bit-aware decode buffer for incremental framing.
BitError
A position-aware bit-codec error (it carries a span-like position). It records the bit offset where decoding/encoding failed and, when the derive can supply it, the field being processed.
BitReader
A cursor that reads values at arbitrary bit offsets from a byte slice, in a chosen BitOrder (MSB-first by default — bit 0 is the high bit of byte 0, the RFC/ETSI ASCII-art convention; LSB-first for serial/PHY layers).
BitWriter
A sink that appends values at arbitrary bit offsets in a chosen BitOrder (MSB-first by default), growing a byte buffer (the final partial byte is zero-padded).
BufSourcestd
A seekable Source over a forward Read (a socket): it retains the bytes it has read, so a seek-using message (restore_position) works over a non-seekable stream by seeking within the retained buffer, reading more on demand. It is bounded — a retention cap (default 64 KiB) past which it errors ErrorKind::BufferFull rather than buffering unboundedly. The “continuously-receiving peer that also needs to seek” case.
BytesReaderbytes
A SeekSource that owns a bytes::Bytes frame (no borrow), decoding bits from it. Constructing it from a Bytes is a refcount bump (zero copy).
BytesWriterbytes
A Sink that encodes into a bytes::BytesMut; freeze hands off a zero-copy Bytes.
CapacityError
The error BitBuf::try_push returns when bytes won’t fit a bounded buffer — the live (unconsumed) bytes plus the new bytes exceed its fixed cap. Grow it with BitBuf::grow, or drain messages with pull before pushing more.
Layout
The wire layout: bit packing order and byte order, threaded through the cursors and entry points. #[bin(big|little)] and #[bin(bits = msb|lsb)] set it; the default is MSB-first, big-endian (RFC/network order).
SeekReaderstd
A SeekSource over a seekable reader (Read + Seek, e.g. a File): it seeks via std::io::Seek to the byte holding the bit cursor, without buffering — the large-file / container-format case. For a non-seekable stream that still needs to seek, use BufSource.
SinkWriterstd
A std::io::Write view over a Sink, from Sink::as_write. Each write pushes 8 bits per byte through Sink::write_bits. The outbound dual of SourceReader; flush is a no-op (the sink owns its buffer).
SourceReaderstd
A std::io::Read view over a Source, from Source::as_read. Each read pulls 8 bits per byte through Source::read_bits, so it works at any bit alignment (you will normally be byte-aligned). A read failure surfaces as an io::Error when no bytes were produced, or ends the read short once some were — the std::io convention. This is the outbound dual of BufSource/SeekReader (which adapt a std::io::Read into a Source).
StreamBitReaderstd
A forward-only bit reader over any std::io::Read — the streaming counterpart to the in-memory BitReader, for a stream you read once and don’t seek.

Enums§

ErrorKind
The cause of a BitError. #[non_exhaustive]: new variants may be added without a major version bump, so match with a wildcard arm.

Traits§

BitAmount
A typed bit/byte amount for positioning directives — 4.bits(), 3.bytes() — resolving to a bit count. Bring it in with use bnb::prelude::*.
BitDecode
A message decoded from a bit stream — the recursion point a #[derive(BitDecode)] struct implements (reading each field in declaration order). Leaf fields are any Bits type; nested messages recurse. Fixed- or variable-length; a fixed-length message also implements FixedBitLen.
BitEncode
A message encoded to a bit stream — the dual of BitDecode.
CountPrefix
Checked length ⇄ wire-prefix conversions: the types usable as a length/count prefix — by the #[brw(count_prefix = <Ty>)] directive and by the codecs::prefixed string codec.
DecodeWith
Polymorphic decode with context A — the companion to a #[bin(ctx(...))] type’s inherent decode_with, for hand-written generic combinators and trait-object parsing (ctx Layer 2). Every BitDecode type is DecodeWith<()> (blanket), and a ctx type is DecodeWith<…Ctx>, so one bound T: DecodeWith<A> spans both context-free and context-taking messages. Inherent Type::decode_with call sites are unaffected.
EncodeExtstd
encode(writer) for any BitEncode message — encodes to a Vec (using the type’s LAYOUT) verbatim and writes it to a std::io::Write sink. A blanket-implemented extension trait, so bring it into scope (use bnb::prelude::* or use bnb::EncodeExt) to call .encode(&mut w). Only with the std feature; in no_std use the generated to_bytes/to_canonical_bytes, or bit_encode/canonical_bit_encode over a Sink.
EncodeWith
The dual of DecodeWith — polymorphic encode with context A.
FixedBitLen
A message whose encoded length is a compile-time constant — i.e. it has no variable-length (count-driven Vec) field. The derive implements this only for fixed messages; it sizes a fixed byte region when the message is embedded as a field in another message (its contribution to the parent’s width). A count-bearing message implements BitDecode/BitEncode but not this. Bits leaves also implement it (their BIT_LEN is Bits::BITS), so a field’s width is computed uniformly whether it’s a leaf or a nested message.
SeekSource
A Source that can seek (its seek_to_bit is real, not the failing default). A #[bin] message that uses restore_position bounds its generated decode on this trait, so a forward-only stream is rejected at compile time. Implemented by BitReader, BufSource, and SeekReader (and, with the bytes feature, BytesReader).
Sink
A bit-level output the codec writes to — the in-memory BitWriter (and, under the bytes feature, BytesWriter). Encode to any std::io::Write via a message’s generated encode method.
Source
A bit-level input the codec recurses over. Implemented by BitReader (in-memory slice), StreamBitReader (forward Read), BufSource (a retain-and-seek socket adapter), and SeekReader (Read + Seek); the codec is generic over Source, so one decoder runs over any of them — see guide::io.