pub struct State { /* private fields */ }Expand description
Gives access to the state of an ongoing serialization or deserialization.
The state acts as a communication channel between the data format and
the types that are serialized or deserialized. It is used in both
directions: Sinks receive it during deserialization
and Serialize implementations and emitters
receive it during serialization. Formats get mutable access to it through
the drivers.
Besides some information about the current position (such as the
depth) it holds typed values that can be used by formats
and types to exchange information that is not part of the data model:
- Extension values (
getandget_mut) remain in the state until they are changed. They are used for information that spans many events such as the current path. - Event data (
eventandevent_mut) is attached to a single event and detached by the drivers after the event was delivered. It is used for information about an individual value, such as a tag.
Some extension values are well-known: the policy for keys that are
given more than once (DuplicateKeys),
the policy for keys that no field of a struct takes
(UnknownFields), how bytes are decoded
from strings (BytesFormat) and the source the
input ranges refer to (Source). They are read and
set with their of and set functions.
Additionally formats can publish the byte range in the input of every
event (see input_range) and extensions can
register types that add context to errors (see
add_error_context).
Extension values have to be Send and Sync so that the state is
too. This means that the state never prevents an ongoing serialization
or deserialization from moving between threads. They are Sync as
event data is recorded (see Recording) and
recordings can be serialized.
Implementations§
Source§impl State
impl State
Sourcepub fn new() -> State
pub fn new() -> State
Creates an empty state.
Drivers create their state, this is useful for code that processes events without a driver.
Sourcepub fn set_collect_errors(&mut self, yes: bool) -> bool
pub fn set_collect_errors(&mut self, yes: bool) -> bool
Sets if maps and sequences collect the errors of their items.
By default the first error ends the deserialization. If errors are
collected, the sinks of the containers that support it (derived
structs and the standard collections) recover from the errors of
their items (see Sink::recover) and
deserialization continues to find the other errors. The container
fails once it’s complete with all errors it collected (see
Error::errors), including the fields that are missing. This
makes it possible to report all problems of the input at once:
use deser::de::DeserializeDriver;
use deser::{Deserialize, Event};
#[derive(Deserialize, Debug)]
struct Server {
host: String,
port: u16,
}
let mut out = None::<Vec<Server>>;
let mut driver = DeserializeDriver::new(&mut out);
driver.state_mut().set_collect_errors(true);
let mut rv = Ok(());
for event in [
Event::seq_start(),
Event::map_start(),
"host".into(),
42u64.into(),
"port".into(),
80u64.into(),
Event::MapEnd,
Event::map_start(),
"host".into(),
"b".into(),
"port".into(),
"http".into(),
Event::MapEnd,
Event::map_start(),
Event::MapEnd,
Event::SeqEnd,
] {
rv = rv.and_then(|()| driver.emit(event));
}
let err = rv.unwrap_err();
let errors: Vec<_> = err.errors().map(|err| err.message()).collect();
assert_eq!(
errors,
[
"unexpected unsigned integer, expected string",
"unexpected string, expected u16",
"missing field `host`",
"missing field `port`",
]
);Types can change this for the values in them, for instance to
collect the errors of a part of the input. The previous setting is
returned. While errors are thrown away (for instance while an
untagged enum tries its variants) they are never collected. See
set_max_errors to limit the number of
errors that are collected.
Sourcepub fn collects_errors(&self) -> bool
pub fn collects_errors(&self) -> bool
Returns true if the errors of items are collected.
See set_collect_errors.
Sourcepub fn set_max_errors(&mut self, max: usize)
pub fn set_max_errors(&mut self, max: usize)
Limits the number of errors that are collected.
Once the limit is reached, the next error ends the deserialization (together with the errors collected so far). By default there is no limit. This counts from the current number of collected errors.
Sourcepub fn error_limit_reached(&self) -> bool
pub fn error_limit_reached(&self) -> bool
Returns true once the limit of errors was reached.
The error that exceeded the limit (see
set_max_errors) ends the deserialization.
Sinks that keep the errors of their values instead of returning
them should return errors once this is set.
Sourcepub fn discards_errors(&self) -> bool
pub fn discards_errors(&self) -> bool
Returns true while errors are thrown away.
While an untagged enum tries its variants only whether a variant accepts the value matters. The errors are created without a message then, and the driver does not attach context to them. Sinks that keep the errors of their values (instead of returning them) should return them while this is set.
Sourcepub fn get<T: Debug + Send + Sync + 'static>(&self) -> Option<&T>
pub fn get<T: Debug + Send + Sync + 'static>(&self) -> Option<&T>
Returns an extension value.
Returns None if the value was never set.
Sourcepub fn get_mut<T: Default + Debug + Send + Sync + 'static>(&mut self) -> &mut T
pub fn get_mut<T: Default + Debug + Send + Sync + 'static>(&mut self) -> &mut T
Returns a mutable extension value.
If the value was never set, it’s initialized with the default value.
Sourcepub fn set_replayable<T: Clone + Default + Debug + Send + Sync + 'static>(
&mut self,
)
pub fn set_replayable<T: Clone + Default + Debug + Send + Sync + 'static>( &mut self, )
Marks an extension type as replayable.
When a value is internally buffered during deserialization (for
instance for internally tagged enums, see
Recording) the values of replayable
extensions are captured for every event and restored when the event is
replayed. This is used for information that changes from event to
event but remains in the state, such as the current path. Event data
is always captured, it does not need to be marked.
Sourcepub fn event<T: Debug + Send + Sync + 'static>(&self) -> Option<&T>
pub fn event<T: Debug + Send + Sync + 'static>(&self) -> Option<&T>
Returns the data of a type attached to the current event.
Returns None if no such data is attached to the event.
Event data is attached to the next event and detached by the driver after that event was delivered:
- During deserialization, formats attach data with
event_mutbefore they emit the event with theDeserializeDriver. The sinks that receive the event (including thefinishof a container on its end event) can access it. - During serialization,
Serializeimplementations and emitters attach data while they produce a value. The format receives it together with the first event of the value from theSerializeDriver.
Event data is captured by a Recording and
restored when the events are replayed.
Sourcepub fn event_mut<T: Default + Clone + Debug + Send + Sync + 'static>(
&mut self,
) -> &mut T
pub fn event_mut<T: Default + Clone + Debug + Send + Sync + 'static>( &mut self, ) -> &mut T
Returns the data of a type attached to the current event mutably.
If no data of this type is attached to the current event yet, the
default value is attached. See event for more
information.
Event data has to be Send and Sync so that it can be captured
(see capture_event_data) without
preventing the captured data from being shared between threads.
Detached values are retained and reused for later events. They are
reset with clone_from from the default value,
which means that types which forward clone_from to their fields
(unlike derived implementations of Clone) reuse the memory of
collections such as Vec.
#[derive(Debug, Default, Clone)]
struct Tags(Vec<u64>);
fn push_tag(state: &mut State, tag: u64) {
state.event_mut::<Tags>().0.push(tag);
}Sourcepub fn take_event<T: Default + Debug + Send + Sync + 'static>(
&mut self,
) -> Option<T>
pub fn take_event<T: Default + Debug + Send + Sync + 'static>( &mut self, ) -> Option<T>
Takes the data of a type from the current event.
Returns None if no such data is attached to the event. Unlike
resetting the data through event_mut this
detaches it, so the data is not captured with the event by the sinks
it’s passed on to (such as the ones of a
Recording). This is what types which
consume event data (like a wrapper which captures a tag) use.
#[derive(Debug, Default, Clone)]
struct Tag(String);
fn take_tag(state: &mut State) -> Option<String> {
state.take_event::<Tag>().map(|tag| tag.0)
}Sourcepub fn capture_event_data(&self) -> EventData
pub fn capture_event_data(&self) -> EventData
Captures the data attached to the current event.
The captured data can be attached to another event later with
attach_event_data. This allows types
which hold values outside of a serialization or deserialization to
retain data like tags (see EventData).
Sourcepub fn attach_event_data(&mut self, data: &EventData)
pub fn attach_event_data(&mut self, data: &EventData)
Attaches captured data to the current event.
Data of the same types that is already attached to the event is
replaced, other data is retained. See
event for when event data is attached and detached.
Sourcepub fn depth(&self) -> usize
pub fn depth(&self) -> usize
Returns the current recursion depth.
This is the number of containers (maps and sequences) that are currently open.
Sourcepub fn container_shape(&self) -> ContainerShape
pub fn container_shape(&self) -> ContainerShape
Sourcepub fn is_map_key(&self) -> bool
pub fn is_map_key(&self) -> bool
Returns true if the value currently being processed is a map key.
Formats which can only represent string keys (such as JSON) emit
them as Atom::Lexical, which the sinks of
the keys parse, so sinks rarely need this.
During serialization this is true while a map key (including the
keys of structs) is serialized and emitted.
Sourcepub fn is_multimap(&self) -> bool
pub fn is_multimap(&self) -> bool
Returns true if the innermost open container is a multimap.
A multimap is a map whose keys can be given more than once (see
ContainerShape::with_multimap). This is the case while its
keys and values are deserialized and while its sink is finished
(in Sink::finish), which includes the
keys and values that flattened fields take. Within a nested map or
sequence it’s the flag of that container.
Sinks that collect the values of repeated keys (derived structs and maps) check this.
Sourcepub fn input_range(&self) -> Option<Range<usize>>
pub fn input_range(&self) -> Option<Range<usize>>
Returns the byte range in the input of the current event.
This is only available if the format provides it (see
set_input_range). The range refers to
the Source and can be resolved into lines and columns for
instance with the deser-location crate.
Sourcepub fn set_input_range(&mut self, start: usize, end: usize)
pub fn set_input_range(&mut self, start: usize, end: usize)
Sets the byte range in the input of the next event.
Formats call this before they emit an event into a
DeserializeDriver. Like event
data, the range is only attached to the next event: the driver
detaches it after the event was delivered.
use deser::de::DeserializeDriver;
let mut out = None::<bool>;
let mut driver = DeserializeDriver::new(&mut out);
driver.state_mut().set_input_range(0, 4);
driver.emit(true).unwrap();
assert_eq!(driver.state().input_range(), None);Sourcepub fn add_error_context<T: ErrorContext>(&mut self)
pub fn add_error_context<T: ErrorContext>(&mut self)
Registers a type that adds context to errors.
When an event fails (for instance because a sink rejects a value)
the drivers invoke ErrorContext::add_context of the registered
types in the order they were registered with the error and the
state as it was when the error happened. This means that the
context is also correct for errors in values which are replayed from
a Recording. The drivers only do this
once for an error: the outer containers which the error passes
through do not add their context.
Registering the same type again has no effect, so this can be called for every event.
use deser::de::DeserializeDriver;
use deser::{Error, ErrorAttachment, ErrorContext, Event, State};
#[derive(Debug)]
struct Depth(usize);
impl ErrorAttachment for Depth {}
impl ErrorContext for Depth {
fn add_context(err: Error, state: &State) -> Error {
match err.attachment::<Depth>() {
Some(_) => err,
None => err.with_attachment(Depth(state.depth())),
}
}
}
let mut out = None::<Vec<Vec<u32>>>;
let mut driver = DeserializeDriver::new(&mut out);
driver.state_mut().add_error_context::<Depth>();
driver.emit(Event::seq_start()).unwrap();
driver.emit(Event::seq_start()).unwrap();
let err = driver.emit(true).unwrap_err();
assert_eq!(err.attachment::<Depth>().unwrap().0, 2);Sourcepub fn attach_error_context(&self, err: Error) -> Error
pub fn attach_error_context(&self, err: Error) -> Error
Attaches the context of the current event to an error.
The drivers do this for the errors of the events that fail (see
add_error_context): the start of the
input range of the event is attached as offset (unless the error
has one) and the registered types add their context. Errors that
already have the context of an event attached are returned
unchanged. This is for sinks that handle the errors of their values
themselves instead of returning them, so that they have the same
context as the errors the driver sees.