Skip to main content

DeserializeDriver

Struct DeserializeDriver 

Source
pub struct DeserializeDriver<'a, 'de: 'a> { /* private fields */ }
Expand description

The driver allows emitting deserialization events into a Deserialize.

This is a convenient way to safely drive a Sink of a Deserialize without using the runtime stack. As rust lifetimes make what this type does internally impossible with safe code, this is a safe abstractiont that hides the unsafety internally.

§Events and Their Context

Events are emitted with emit or, if they borrow from the data being deserialized, with emit_borrowed. Information about the next event is placed into the State before it’s emitted: its byte range in the input with State::set_input_range and data attached to it with State::event_mut. Both are detached after the event was delivered.

use deser::de::DeserializeDriver;
use deser::Event;

let mut out = None::<Vec<u32>>;
let mut driver = DeserializeDriver::new(&mut out);
driver.state_mut().set_input_range(0, 1);
driver.emit(Event::seq_start()).unwrap();
driver.state_mut().set_input_range(1, 3);
driver.emit(42u64).unwrap();
driver.state_mut().set_input_range(3, 4);
driver.emit(Event::SeqEnd).unwrap();

When an event fails, the error gets the context of the event attached (see Error and State::add_error_context).

§Layers

Layers sit between the format and the sinks and see every event before it’s delivered. They are added with push_layer, see Layer for more information.

Implementations§

Source§

impl<'a, 'de> DeserializeDriver<'a, 'de>

Source

pub fn new<T: Deserialize<'de>>( out: &'a mut Option<T>, ) -> DeserializeDriver<'a, 'de>

Creates a new deserializer driver.

Source

pub fn update<T: Deserialize<'de>>( value: &'a mut T, ) -> DeserializeDriver<'a, 'de>

Creates a driver that updates an existing value.

See Deserialize::deserialize_update.

use deser::de::DeserializeDriver;
use deser::{Deserialize, Event};

#[derive(Deserialize)]
struct Config {
    host: String,
    port: u16,
}

let mut config = Config { host: "localhost".into(), port: 80 };
let mut driver = DeserializeDriver::update(&mut config);
for event in [
    Event::map_start(),
    "port".into(),
    8080u64.into(),
    Event::MapEnd,
] {
    driver.emit(event).unwrap();
}
drop(driver);
assert_eq!((config.host.as_str(), config.port), ("localhost", 8080));
Source

pub fn from_sink(sink: SinkHandle<'a, 'de>) -> DeserializeDriver<'a, 'de>

Creates a new deserializer driver from a sink.

The sink cannot be allocated in the arena of the driver, see from_fn for that.

Source

pub fn from_fn( make: impl FnOnce(&mut State) -> SinkHandle<'a, 'de>, ) -> DeserializeDriver<'a, 'de>

Creates a new deserializer driver with a sink that is created with the state of the driver.

This allows the sink to be allocated in the arena of the driver (see SinkHandle::arena).

use deser::de::{DeserializeDriver, Recording};
use deser::Event;

let mut recording = Recording::new();
let mut driver =
    DeserializeDriver::from_fn(|state| recording.recorder(state));
for event in [Event::seq_start(), 42u64.into(), Event::SeqEnd] {
    driver.emit(event).unwrap();
}
drop(driver);
assert_eq!(recording.events().count(), 3);
Source

pub fn from_state( state: State, sink: SinkHandle<'a, 'de>, ) -> DeserializeDriver<'a, 'de>

Creates a driver from a state and a sink that was created with it.

This is like from_fn for code that creates the sink where the type is known and runs the driver in a function that is not generic.

Source

pub fn state(&self) -> &State

Returns a borrowed reference to the current deserializer state.

Source

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

Returns a mutable reference to the current deserializer state.

Formats use this to publish information for the event they emit next into the state.

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 emitted into the driver, the last one passes them on to the sinks. See Layer for more information.

Source

pub fn wrap_sink<F>(&mut self, f: F)
where F: for<'x> FnOnce(SinkHandle<'x, 'de>, &mut State) -> SinkHandle<'x, 'de>,

Wraps the sink the driver deserializes into.

This allows placing a sink between the driver and the sink of a value, for instance to change how certain values are deserialized. Unlike Layers such sinks see the sinks of the values and not just the events. Sinks created by a wrapped sink are not wrapped automatically, the wrapper needs to wrap them in next_key and next_value if it wants to see them.

§Panics

Panics if events were already emitted.

Source

pub fn emit<'e, E: Into<Event<'e>>>(&mut self, event: E) -> Result<(), Error>

Emits an event into the driver.

The data of the event is only valid for the call. To emit data that can be borrowed use emit_borrowed.

§Panics

The driver keeps an internal state and emitting events when they are not expected will cause the driver to panic.

Source

pub fn emit_borrowed<E: Into<Event<'de>>>( &mut self, event: E, ) -> Result<(), Error>

Emits an event that borrows from the data being deserialized.

This is like emit but atoms are passed to Sink::borrowed_atom which means that types like &str can borrow them:

use deser::de::DeserializeDriver;

let input = String::from("hello");
let mut out = None::<&str>;
{
    let mut driver = DeserializeDriver::new(&mut out);
    driver.emit_borrowed(input.as_str()).unwrap();
}
assert_eq!(out, Some("hello"));
Source

pub fn transient<'f, R>( &mut self, f: impl FnOnce(&mut DeserializeDriver<'_, 'f>) -> R, ) -> R
where 'de: 'f,

Lends the driver out for data that lives shorter than 'de.

The callback receives the driver with the lifetime 'f for borrowed data. Events emitted with emit_borrowed within it are delivered like the ones emitted with emit: types that keep the data copy it and types which can only borrow (like &str) fail. This allows data that only lives for a call (like the frame of a value in a stream buffer) to be deserialized with code that borrows from its input into a driver for any lifetime:

use deser::de::DeserializeDriver;

/// Emits the words of the input, borrowing from it.
fn words<'de>(input: &'de str, driver: &mut DeserializeDriver<'_, 'de>) {
    driver.emit(deser::Event::seq_start()).unwrap();
    for word in input.split(' ') {
        driver.emit_borrowed(word).unwrap();
    }
    driver.emit(deser::Event::SeqEnd).unwrap();
}

let mut out = None::<Vec<String>>;
{
    let mut driver = DeserializeDriver::new(&mut out);
    let input = String::from("hello world");
    driver.transient(|driver| words(&input, driver));
}
assert_eq!(out.unwrap(), ["hello", "world"]);
§Panics

Panics if the callback replaces the driver (for instance with mem::swap), the driver cannot be used after that. Wrapping the sink (wrap_sink) in the callback panics as well.

Auto Trait Implementations§

§

impl<'a, 'de> !RefUnwindSafe for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> !Sync for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> !Unpin for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> !UnwindSafe for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> Freeze for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> Send for DeserializeDriver<'a, 'de>

§

impl<'a, 'de> UnsafeUnpin for DeserializeDriver<'a, 'de>

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.