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>
impl<'a, 'de> DeserializeDriver<'a, 'de>
Sourcepub fn new<T: Deserialize<'de>>(
out: &'a mut Option<T>,
) -> DeserializeDriver<'a, 'de>
pub fn new<T: Deserialize<'de>>( out: &'a mut Option<T>, ) -> DeserializeDriver<'a, 'de>
Creates a new deserializer driver.
Sourcepub fn update<T: Deserialize<'de>>(
value: &'a mut T,
) -> DeserializeDriver<'a, 'de>
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));Sourcepub fn from_sink(sink: SinkHandle<'a, 'de>) -> DeserializeDriver<'a, 'de>
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.
Sourcepub fn from_fn(
make: impl FnOnce(&mut State) -> SinkHandle<'a, 'de>,
) -> DeserializeDriver<'a, 'de>
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);Sourcepub fn from_state(
state: State,
sink: SinkHandle<'a, 'de>,
) -> DeserializeDriver<'a, 'de>
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.
Sourcepub fn state_mut(&mut self) -> &mut State
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.
Sourcepub fn push_layer<L: Layer + 'static>(&mut self, layer: L)
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.
Sourcepub fn wrap_sink<F>(&mut self, f: F)
pub fn wrap_sink<F>(&mut self, f: F)
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.
Sourcepub fn emit<'e, E: Into<Event<'e>>>(&mut self, event: E) -> Result<(), Error>
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.
Sourcepub fn emit_borrowed<E: Into<Event<'de>>>(
&mut self,
event: E,
) -> Result<(), Error>
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"));Sourcepub fn transient<'f, R>(
&mut self,
f: impl FnOnce(&mut DeserializeDriver<'_, 'f>) -> R,
) -> Rwhere
'de: 'f,
pub fn transient<'f, R>(
&mut self,
f: impl FnOnce(&mut DeserializeDriver<'_, 'f>) -> R,
) -> Rwhere
'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.