Skip to main content

Framer

Trait Framer 

Source
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::unbounded(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§

Source

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.

Source

fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>

Serialize payload as a single frame into out.

The built-in framers are atomic: on error, out is left at its original position.

§Errors

Implementation-defined; see each concrete framer.

Provided Methods§

Source

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);
Source

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::unbounded(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".

Implementors§