pub trait Framer {
// Required methods
fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>;
fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>;
// Provided methods
fn next_frame_from<'a>(
&self,
input: &'a [u8],
scanned: &mut usize,
) -> Result<Option<Frame<'a>>> { ... }
fn max_frame_len(&self, payload_len: usize) -> Option<usize> { ... }
}Expand description
Strategy that extracts and emits one frame at a time.
Implementations are stateless: each call to Framer::next_frame is
independent. To process a stream, the caller advances their own read
position by Frame::consumed after each successful call.
§Example
use wire_codec::framing::{Framer, LengthPrefixed, LengthWidth, Endian};
let framer = LengthPrefixed::new(LengthWidth::U16, Endian::Big);
let input = &[0x00, 0x03, b'h', b'i', b'!'];
let frame = framer.next_frame(input).unwrap().unwrap();
assert_eq!(frame.payload(), b"hi!");
assert_eq!(frame.consumed(), 5);Required Methods§
Sourcefn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
Try to extract a single frame from the start of input.
Returns Ok(Some(frame)) when a complete frame is available,
Ok(None) when more bytes are needed, and Err(_) when the input
violates the protocol.
§Errors
Implementation-defined; see each concrete framer for its error contract.
Provided Methods§
Sourcefn next_frame_from<'a>(
&self,
input: &'a [u8],
scanned: &mut usize,
) -> Result<Option<Frame<'a>>>
fn next_frame_from<'a>( &self, input: &'a [u8], scanned: &mut usize, ) -> Result<Option<Frame<'a>>>
Resumable variant of Framer::next_frame for streaming input.
scanned is a progress hint owned by the caller. Start it at 0.
Between calls the caller may only append bytes to input; when a call
returns Ok(Some(frame)), the framer resets scanned to 0 and the
caller drops frame.consumed() bytes from the front before the next
call. A framer that searches its input (such as Delimited) records
how far it got on Ok(None) and continues from there next time, which
turns a byte-at-a-time stream from quadratic into linear work.
If the buffered input is discarded or replaced (for example after an
error), set scanned back to 0; a stale hint would make the framer
skip bytes it has never examined.
The default implementation ignores the hint and calls
Framer::next_frame, which is optimal for framers that read a
fixed-position header. StreamDecoder manages the hint for you.
§Errors
Same contract as Framer::next_frame.
§Example
use wire_codec::framing::{Delimited, Framer};
let framer = Delimited::bounded(b"\n").unwrap();
let mut scanned = 0;
assert_eq!(framer.next_frame_from(b"hel", &mut scanned).unwrap(), None);
assert_eq!(scanned, 3);
let frame = framer.next_frame_from(b"hello\n", &mut scanned).unwrap().unwrap();
assert_eq!(frame.payload(), b"hello");
assert_eq!(scanned, 0);Sourcefn max_frame_len(&self, payload_len: usize) -> Option<usize>
fn max_frame_len(&self, payload_len: usize) -> Option<usize>
Upper bound on the number of bytes Framer::write_frame writes for
a payload of payload_len bytes.
Returns None when the framer cannot say, or when the bound would
overflow usize. Buffer-growing adapters (such as the optional
bytes codec) use it to reserve space in one step. The default
implementation returns None.
§Example
use wire_codec::framing::{Endian, Framer, LengthPrefixed, LengthWidth};
let framer = LengthPrefixed::new(LengthWidth::U32, Endian::Big);
assert_eq!(framer.max_frame_len(10), Some(14));Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".