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 the Sink
of a Deserialize without using the call stack for nesting. As Rust
lifetimes make what this type does internally impossible with safe
code, this is a safe abstraction 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 multimap_value<T: Deserialize<'de>>(
out: &'a mut Option<T>,
) -> DeserializeDriver<'a, 'de>
pub fn multimap_value<T: Deserialize<'de>>( out: &'a mut Option<T>, ) -> DeserializeDriver<'a, 'de>
Creates a driver for one value of a key in a multimap.
In a multimap (see
ContainerShape::set_multimap)
collections like Vec<T> and sets collect the values of a repeated
key. This deserializes a value as if it was the only value of such
a key: collections take it as their only item, other types are
deserialized like with new. Formats that read a
single value of a key (like an environment variable) use this, see
missing_multimap_value for a
key that is missing.
use deser::de::DeserializeDriver;
let mut out = None::<Vec<u16>>;
DeserializeDriver::multimap_value(&mut out).emit(80u64).unwrap();
assert_eq!(out, Some(vec![80]));
let mut out = None::<u16>;
DeserializeDriver::multimap_value(&mut out).emit(80u64).unwrap();
assert_eq!(out, Some(80));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_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). The function can also return a sink
that exists already (for instance with SinkHandle::to).
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 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 set_context(&mut self, context: Context)
pub fn set_context(&mut self, context: Context)
Sets the context of the deserialization.
The values of the context are the defaults of the extension values
of the state (see Context). This replaces the context of the
driver. Formats add the values of their own context for the types
it has no value for (see
set_default_context). If the
context has Limits, the driver enforces them: they see the
events as the sinks receive them, after all layers (see
push_layer). This way the errors of the
limits have the context the layers add (like the path).
Sourcepub fn set_default_context(&mut self, context: Context)
pub fn set_default_context(&mut self, context: Context)
Adds the values of a context that the context of the driver has no value for.
Formats use this for the context they were given (for instance the
one of their configuration). A context that was set on the driver
before (for instance in the setup callback of
Deserializer::deserialize_with)
takes precedence: its values are kept and the values of the given
context are only added for the types it has no value for.
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 (or the Limits of the context,
see set_context). 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.