pub struct Delimited<'d> { /* private fields */ }Expand description
Byte-delimited framer.
§Example
use wire_codec::WriteBuf;
use wire_codec::framing::{Delimited, Framer};
let framer = Delimited::bounded(b"\n").unwrap();
let mut out = [0u8; 32];
let mut buf = WriteBuf::new(&mut out);
framer.write_frame(b"line one", &mut buf).unwrap();
framer.write_frame(b"line two", &mut buf).unwrap();
let n = buf.position();
assert_eq!(&out[..n], b"line one\nline two\n");
let first = framer.next_frame(&out[..n]).unwrap().unwrap();
assert_eq!(first.payload(), b"line one");
assert_eq!(first.consumed(), 9);Implementations§
Source§impl<'d> Delimited<'d>
impl<'d> Delimited<'d>
Sourcepub const DEFAULT_MAX_PAYLOAD: usize
pub const DEFAULT_MAX_PAYLOAD: usize
Payload limit applied by Delimited::bounded: 64 KiB.
Generous for line-oriented text protocols (SMTP caps a line at 1000 bytes, HTTP servers commonly cap a header line at 8 KiB) while bounding the memory a single peer can pin.
Sourcepub const fn new(delimiter: &'d [u8]) -> Result<Self>
👎Deprecated since 1.2.0: unbounded: no payload limit at all. Use Delimited::bounded or Delimited::bounded_to for peer input, or Delimited::unbounded to keep this behaviour
pub const fn new(delimiter: &'d [u8]) -> Result<Self>
unbounded: no payload limit at all. Use Delimited::bounded or Delimited::bounded_to for peer input, or Delimited::unbounded to keep this behaviour
Build an unbounded framer using delimiter to separate frames.
Warning: there is no payload size limit. The framer keeps asking
for more input until it sees the delimiter, however long that takes,
so a peer that never sends it makes a streaming reader buffer without
a ceiling. Use Delimited::bounded (64 KiB) or
Delimited::bounded_to for input from untrusted peers, and
Delimited::unbounded where no limit is really wanted. new
becomes bounded in 2.0.
§Errors
Returns Error::EmptyDelimiter if delimiter is empty. An empty
delimiter cannot uniquely separate frames.
§Example
use wire_codec::framing::Delimited;
let framer = Delimited::new(b"\r\n").unwrap();
assert_eq!(framer.max_payload(), usize::MAX);Sourcepub const fn unbounded(delimiter: &'d [u8]) -> Result<Self>
pub const fn unbounded(delimiter: &'d [u8]) -> Result<Self>
Build a framer with no payload size limit: the behaviour of new
before 1.2.0, under a name that says so.
Only for input whose size is already bounded by other means. For peer
input use Delimited::bounded or Delimited::bounded_to.
§Errors
Returns Error::EmptyDelimiter if delimiter is empty.
§Example
use wire_codec::framing::Delimited;
let framer = Delimited::unbounded(b"\r\n").unwrap();
assert_eq!(framer.max_payload(), usize::MAX);Sourcepub const fn bounded_to(delimiter: &'d [u8], max: usize) -> Result<Self>
pub const fn bounded_to(delimiter: &'d [u8], max: usize) -> Result<Self>
Build a framer using delimiter, capped at max payload bytes per
frame. Equivalent to Delimited::unbounded(delimiter)?.with_max_payload(max).
§Errors
Returns Error::EmptyDelimiter if delimiter is empty.
§Example
use wire_codec::framing::{Delimited, Framer};
use wire_codec::Error;
let framer = Delimited::bounded_to(b"\n", 4).unwrap();
assert!(framer.next_frame(b"1234\n").unwrap().is_some());
assert!(matches!(
framer.next_frame(b"123456"),
Err(Error::FrameTooLarge { limit: 4, .. })
));Sourcepub const fn bounded(delimiter: &'d [u8]) -> Result<Self>
pub const fn bounded(delimiter: &'d [u8]) -> Result<Self>
Build a framer using delimiter, capped at
Delimited::DEFAULT_MAX_PAYLOAD payload bytes per frame.
This is the recommended constructor for input from untrusted peers.
Chain Delimited::with_max_payload to pick a different cap.
§Errors
Returns Error::EmptyDelimiter if delimiter is empty.
§Example
use wire_codec::framing::Delimited;
let framer = Delimited::bounded(b"\n").unwrap();
assert_eq!(framer.max_payload(), Delimited::DEFAULT_MAX_PAYLOAD);Sourcepub const fn with_max_payload(self, max: usize) -> Self
pub const fn with_max_payload(self, max: usize) -> Self
Set an upper bound on payload size. Frames whose payload would exceed
this size cause Error::FrameTooLarge.
The delimiter search never looks further than max + delimiter.len()
bytes into the input, so the limit also bounds the work per call.
§Example
use wire_codec::framing::{Delimited, Framer};
use wire_codec::Error;
let framer = Delimited::unbounded(b"\n").unwrap().with_max_payload(4);
assert!(framer.next_frame(b"1234\n").unwrap().is_some());
assert!(matches!(
framer.next_frame(b"123456"),
Err(Error::FrameTooLarge { limit: 4, .. })
));Sourcepub const fn max_payload(&self) -> usize
pub const fn max_payload(&self) -> usize
Configured maximum payload size.
Trait Implementations§
impl<'d> Copy for Delimited<'d>
impl<'d> Eq for Delimited<'d>
Source§impl Framer for Delimited<'_>
impl Framer for Delimited<'_>
Source§fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
fn next_frame<'a>(&self, input: &'a [u8]) -> Result<Option<Frame<'a>>>
Extract the bytes up to the first delimiter.
§Errors
Returns Error::FrameTooLarge once more than
max_payload + delimiter.len() bytes are buffered without a
delimiter starting at or before offset max_payload. The len field
is then a lower bound (max_payload + 1): the true length is unknown
because the frame has not ended yet.
Source§fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
fn write_frame(&self, payload: &[u8], out: &mut WriteBuf<'_>) -> Result<()>
Serialize payload followed by the delimiter.
§Errors
Error::FrameTooLargeifpayloadexceeds the configured limit.Error::DelimiterInPayloadif the receiver would not read the payload back as a single frame: eitherpayloadcontains the delimiter, or (for a self-overlapping delimiter such asb"aa") the payload ends in a way that makes a delimiter appear earlier than intended (b"a"followed byb"aa"reads back as an empty frame).Error::BufferFullifoutcannot hold the payload and the delimiter.
Nothing is written on error.
Source§fn 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 delimiter search; see Framer::next_frame_from.
On Ok(None), scanned is set to the number of leading bytes that
can no longer start a delimiter, so the next call only examines new
input (plus delimiter.len() - 1 bytes of overlap for a delimiter
split across reads). Values larger than the input are clamped.
§Errors
Same contract as Framer::next_frame for this type.
Source§fn max_frame_len(&self, payload_len: usize) -> Option<usize>
fn max_frame_len(&self, payload_len: usize) -> Option<usize>
Framer::write_frame writes for
a payload of payload_len bytes. Read more