Skip to main content

JsonFrameBuffer

Struct JsonFrameBuffer 

Source
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. Call reset when 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

Source

pub fn new() -> Self

Creates an empty buffer.

Source

pub fn pending(&self) -> &str

The text received but not yet returned: an unfinished value, or text that cannot start one.

Source

pub fn is_empty(&self) -> bool

Whether nothing is pending. Whitespace-only input counts as nothing.

Source

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.

Source

pub fn reset(&mut self)

Throws away everything pending.

Trait Implementations§

Source§

impl Clone for JsonFrameBuffer

Source§

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)

Performs copy-assignment from source. Read more
Source§

impl Debug for JsonFrameBuffer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for JsonFrameBuffer

Source§

fn default() -> JsonFrameBuffer

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.