pub struct JsonFrameBuffer { /* private fields */ }Expand description
Puts the pieces of a JSON stream back together and cuts it into whole top-level values.
Some WebSocket servers split one JSON message over several text frames, or glue several
messages into one frame. Feed every received chunk to push. It keeps the
unfinished tail and returns each complete top-level object or array.
What it does and does not do:
- It counts brackets and understands strings and escapes, so a brace inside
"..."does not end a value. - It does not check that the text is valid JSON.
{not json}is returned as a complete value. Parse each returned string yourself. - Only values that start with
{or[are recognised. If the pending text starts with anything else (a bare number, a word, a stray}), nothing is ever returned and the text stays in the buffer, growing with every chunk. Callresetwhen the stream is reconnected or corrupt.
§Examples
use brokapi_sansio::{BufferPush, JsonFrameBuffer};
let mut buf = JsonFrameBuffer::new();
// One message arrives in two pieces.
assert_eq!(buf.push(r#"{"op":"quote","bid":"#), BufferPush::Incomplete);
assert_eq!(
buf.push(r#"100}"#),
BufferPush::Complete(vec![r#"{"op":"quote","bid":100}"#.to_string()]),
);
// Two messages arrive glued together, and a third starts.
let got = buf.push(r#"{"a":1} {"b":"}"} {"c""#);
assert_eq!(
got,
BufferPush::Complete(vec![r#"{"a":1}"#.to_string(), r#"{"b":"}"}"#.to_string()]),
);
assert_eq!(buf.pending(), r#"{"c""#);
// The caller can drop a half-received message, for example after a reconnect.
buf.reset();
assert!(buf.is_empty());
// Text that cannot start a value blocks the buffer, even if a good value follows it.
assert_eq!(buf.push(r#"oops {"a":1}"#), BufferPush::Incomplete);
assert!(!buf.is_empty());
buf.reset();Implementations§
Source§impl JsonFrameBuffer
impl JsonFrameBuffer
Sourcepub fn pending(&self) -> &str
pub fn pending(&self) -> &str
The text received but not yet returned: an unfinished value, or text that cannot start one.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether nothing is pending. Whitespace-only input counts as nothing.
Sourcepub fn push(&mut self, chunk: &str) -> BufferPush
pub fn push(&mut self, chunk: &str) -> BufferPush
Appends a chunk and returns every complete top-level value that is now available.
The returned strings are in arrival order. What follows them stays in the buffer. See the type docs for what is not checked.
Trait Implementations§
Source§impl Clone for JsonFrameBuffer
impl Clone for JsonFrameBuffer
Source§fn clone(&self) -> JsonFrameBuffer
fn clone(&self) -> JsonFrameBuffer
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for JsonFrameBuffer
impl Debug for JsonFrameBuffer
Source§impl Default for JsonFrameBuffer
impl Default for JsonFrameBuffer
Source§fn default() -> JsonFrameBuffer
fn default() -> JsonFrameBuffer
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for JsonFrameBuffer
impl RefUnwindSafe for JsonFrameBuffer
impl Send for JsonFrameBuffer
impl Sync for JsonFrameBuffer
impl Unpin for JsonFrameBuffer
impl UnsafeUnpin for JsonFrameBuffer
impl UnwindSafe for JsonFrameBuffer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more