Skip to main content

SerializeDriver

Struct SerializeDriver 

Source
pub struct SerializeDriver<'a> { /* private fields */ }
Expand description

The driver allows serializing a Serialize iteratively.

This is the only way to convert from a Serialize into an event stream. As a user one has to call next until None is returned, indicating the end of the event stream, or use drive.

When the serialization fails, the error gets the context of the current value attached (see State::add_error_context).

§Layers

Layers sit between the serialized values and the format and see every event before the format receives it. They are added with push_layer and are only supported by drive.

Implementations§

Source§

impl<'a> SerializeDriver<'a>

Source

pub fn new(serializable: &'a dyn Serialize) -> SerializeDriver<'a>

Creates a new driver which serializes the given value implementing Serialize.

Source

pub fn state(&self) -> &State

Returns a borrowed reference to the current serializer state.

Source

pub fn state_mut(&mut self) -> &mut State

Returns a mutable reference to the current serializer state.

This can be used to place extension values into the state which the serializable values can then pick up.

Source

pub fn push_layer<L: Layer + 'static>(&mut self, layer: L)

Adds a layer.

Layers see the events in the order they were added: the layer that was added first sees the events produced by the values, the last one passes them on to the format. See Layer for more information.

Source

pub fn next( &mut self, ) -> Result<Option<(Event<'_>, &dyn Serialize, &mut State)>, Error>

Produces the next serialization event.

§Panics

The driver will panic if the data fed from the serializer is malformed. As layers can change the number of events, this method panics if layers were added.

Source

pub fn drive<F>(&mut self, f: F) -> Result<(), Error>
where F: FnMut(Event<'_>, &mut State) -> Result<(), Error>,

Drives the serialization to the end and invokes a callback for every event.

This produces the same events as calling next until it returns None but it’s faster. The first error (either produced by a serializable or returned by the callback) aborts the serialization.

let serializable = vec!["foo", "bar", "baz"];
let mut events = Vec::new();
SerializeDriver::new(&serializable).drive(|event, _state| {
    events.push(event.to_static());
    Ok(())
})?;
assert_eq!(events.len(), 5);
Source

pub fn drive_sink<S: EventSink>(&mut self, sink: &mut S) -> Result<(), Error>

Like drive but delivers the events to an EventSink.

Source

pub fn drive_until<S: PausableSink>( &mut self, sink: &mut S, ) -> Result<bool, Error>

Drives the serialization until it’s complete or the sink pauses it.

Returns true once the serialization is complete. If the sink paused the driver (see PausableSink::pause), false is returned and the next call continues where this one stopped. At least one value is serialized per call.

Unlike drive, which emits values that only hold atoms (like a Vec<u64>) at once, the driver emits such values in pieces of a few hundred atoms and can pause in between. The amount of events between two pauses only depends on the size of the atoms, not on the size of the value.

/// Collects events and pauses once it holds 100.
struct Collect(Vec<Event<'static>>);

impl PausableSink for Collect {
    fn event(
        &mut self,
        event: Event<'_>,
        _value: &dyn Serialize,
        _state: &mut State,
    ) -> Result<(), Error> {
        self.0.push(event.to_static());
        Ok(())
    }

    fn pause(&mut self) -> bool {
        self.0.len() >= 100
    }
}

let value: Vec<u64> = (0..10_000).collect();
let mut driver = SerializeDriver::new(&value);
let mut sink = Collect(Vec::new());
let mut events = 0;
loop {
    let done = driver.drive_until(&mut sink)?;
    // the events so far are processed while the driver is paused
    assert!(sink.0.len() < 1000);
    events += sink.0.len();
    sink.0.clear();
    if done {
        break;
    }
}
assert_eq!(events, 10_002);
Source

pub fn drive_described<F>(&mut self, f: F) -> Result<(), Error>
where F: FnMut(Event<'_>, &dyn Serialize, &mut State) -> Result<(), Error>,

Like drive but the callback also receives the value of every event.

The value is intended to be described by formats that reflect the Rust shape of values. Formats that do not need it should use drive which is faster.

struct IsSome(bool);

impl Describe for IsSome {
    fn some(&mut self) {
        self.0 = true;
    }
}

let mut some = Vec::new();
let value = vec![Some(1), None];
SerializeDriver::new(&value).drive_described(|_event, value, _state| {
    let mut describer = IsSome(false);
    value.describe(&mut describer);
    some.push(describer.0);
    Ok(())
})?;
assert_eq!(some, [false, true, false, false]);

Trait Implementations§

Source§

impl<'a> Drop for SerializeDriver<'a>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for SerializeDriver<'a>

§

impl<'a> !Sync for SerializeDriver<'a>

§

impl<'a> !Unpin for SerializeDriver<'a>

§

impl<'a> !UnwindSafe for SerializeDriver<'a>

§

impl<'a> Freeze for SerializeDriver<'a>

§

impl<'a> Send for SerializeDriver<'a>

§

impl<'a> UnsafeUnpin for SerializeDriver<'a>

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.