1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//! # 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
//!
//! | Module | Provides |
//! | ------ | -------- |
//! | [`buf`] | [`ReadBuf`] and [`WriteBuf`], the zero-copy byte cursors every other module is built on. |
//! | [`error`] | [`Error`] and [`Result`], the crate-wide error contract. |
//! | [`traits`] | [`Encode`] and [`Decode`], the codec trait pair, with impls for primitives, arrays, tuples, and the [`Be`] / [`Le`] / [`Varint`] wrappers. |
//! | [`varint`] | LEB128 varint for `u16`, `u32`, `u64`, `usize`, and zigzag `i32` / `i64`, with canonical (strict) decoders. |
//! | [`zigzag`] | Signed-to-unsigned mapping for compact signed varints. |
//! | [`bitfield`] | [`BitReader`] and [`BitWriter`] for MSB-first packed bits. |
//! | [`packed`] | [`packed_struct!`] and the [`PackedField`][`packed::PackedField`] trait for bit-packed structs. |
//! | [`framing`] | The [`Framer`][`framing::Framer`] trait, [`StreamDecoder`][`framing::StreamDecoder`], and the [`LengthPrefixed`][`framing::LengthPrefixed`], [`VarintPrefixed`][`framing::VarintPrefixed`], [`Delimited`][`framing::Delimited`], and [`Checksummed`][`framing::Checksummed`] strategies. |
//! | [`checksum`] | The [`Checksum`][`checksum::Checksum`] trait and CRC-16/CCITT-FALSE, CRC-32, CRC-32C. |
//! | [`cobs`] | Consistent Overhead Byte Stuffing. |
//! | `codec` | `FrameCodec`, 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`][`framing::Checksummed`] around a custom framer that
//! reports no [`max_frame_len`][`framing::Framer::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`][`framing::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:
//!
//! - New [`Error`] variants ([`Error`] is `#[non_exhaustive]`).
//! - New [`framing::LengthWidth`] widths ([`framing::LengthWidth`] is
//! `#[non_exhaustive]`).
//! - New methods on existing types, and new provided methods on traits.
//! - Additional features behind feature flags.
//!
//! 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
//!
//! | Feature | Default | Effect |
//! | ------- | ------- | ------ |
//! | `std` | yes | Links the standard library and adds `From<Error> for std::io::Error`. Drop it for `no_std` targets; [`Error`] implements `core::error::Error` either way. |
//! | `memchr` | no | Delimiter search through the `memchr` crate (SIMD, linear-time multi-byte search) instead of the built-in SWAR scan. |
//! | `bytes` | no | The `codec` module: `FrameCodec` over `bytes::BytesMut`. Works without `std`. |
//! | `tokio-util` | no | `tokio_util::codec::{Decoder, Encoder}` for `FrameCodec`. Implies `bytes` and `std`. |
//! | `asynchronous-codec` | no | `asynchronous_codec::{Decoder, Encoder}` for `FrameCodec`. Implies `bytes` and `std`. |
//!
//! # License
//!
//! Dual-licensed under Apache-2.0 OR MIT.
// Unit tests always link `std` (for `Vec`, `String`, formatting); the library
// itself is `no_std` whenever the `std` feature is off.
// REPS-mandated lint set. Keep aligned with REPS.md "Compiler & Lint Configuration".
// The crate contains no `unsafe` code; `forbid` makes that machine-checked.
pub use ;
pub use ;
pub use ;
pub use ;
/// Crate version string, populated by Cargo at build time.
///
/// # Example
///
/// ```
/// assert!(wire_codec::VERSION.starts_with("1."));
/// ```
pub const VERSION: &str = env!;
/// Compiles the README code blocks as doctests so they cannot drift.
;
/// Compiles the `docs/API.md` code blocks as doctests so they cannot drift.
;