pub struct NdjsonDecoder { /* private fields */ }Expand description
An incremental NDJSON framer: push bytes, take complete lines.
NdjsonStream drives one over a byte stream; use it directly when the
bytes do not come as a Stream (a callback API, a test).
Framing is linear: each byte is scanned for a line ending once, however
the chunks split the lines. A size cap
(max_line_size) bounds the line still waiting
for its ending, where memory grows from chunk to chunk.
use allama_http::ndjson::NdjsonDecoder;
let mut decoder = NdjsonDecoder::new();
decoder.push(b"{\"a\":1}\r");
assert_eq!(decoder.next_line(), Ok(None));
decoder.push(b"\n\n{\"b\":");
assert_eq!(decoder.next_line(), Ok(Some(r#"{"a":1}"#.to_owned())));
assert_eq!(decoder.next_line(), Ok(None));
decoder.push(b"2}");
// The body ended: the last line needs no line ending.
assert_eq!(decoder.finish(), Ok(Some(r#"{"b":2}"#.to_owned())));Implementations§
Source§impl NdjsonDecoder
impl NdjsonDecoder
Sourcepub const DEFAULT_MAX_LINE_SIZE: usize
pub const DEFAULT_MAX_LINE_SIZE: usize
The default max_line_size: 64 MiB, as
SseDecoder::DEFAULT_MAX_EVENT_SIZE,
for the same reasons: a final line can repeat the whole response,
and streamed base64 images are large.
Sourcepub fn max_line_size(self, limit: usize) -> Self
pub fn max_line_size(self, limit: usize) -> Self
Set the size cap, in bytes (default
DEFAULT_MAX_LINE_SIZE).
It bounds a line, its line ending excluded. push
checks the line still waiting for its ending before it buffers a
chunk, so that line never grows much past the cap.
Past the cap, next_line fails with
NdjsonError::LineTooLarge, and framing cannot go on: the framer
drops what it holds, ignores later bytes and keeps returning the
error.
use allama_http::ndjson::{NdjsonDecoder, NdjsonError};
let mut decoder = NdjsonDecoder::new().max_line_size(8);
decoder.push(b"{\"a\":12}");
assert_eq!(decoder.next_line(), Ok(None));
// A 9th byte without a line ending.
decoder.push(b"3");
assert!(matches!(
decoder.next_line(),
Err(NdjsonError::LineTooLarge { limit: 8, .. })
));Sourcepub fn next_line(&mut self) -> Result<Option<String>, NdjsonError<Infallible>>
pub fn next_line(&mut self) -> Result<Option<String>, NdjsonError<Infallible>>
The next complete, non-blank line, without its line ending, or
None until more bytes arrive.
§Errors
NdjsonError::InvalidUtf8when a line is not valid UTF-8. The line is skipped, and framing can go on, but the stream is corrupt:NdjsonStreamends there.NdjsonError::LineTooLargepast the size cap. Framing cannot go on.
A framer fails with no other error: it reads no transport.