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: Deserialize implementations and
Sinks receive it during deserialization and
Serialize implementations and emitters
receive it during serialization. Formats get mutable access to it through
the drivers. The state also holds the arena the sinks and emitters are
allocated in (see SinkHandle::arena
and Emit::seq).
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).
The extension values default to the values of the Context of the
serialization or deserialization (see set_context):
the context is the configuration given from the outside, the state holds
what changes while values are processed.
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)
pub fn set_collect_errors(&mut self, yes: 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::Deserializer;
use deser::Deserialize;
#[derive(Deserialize, Debug)]
struct Server {
host: String,
port: u16,
}
let input = r#"[
{"host": 42, "port": 80},
{"host": "b", "port": "http"},
{}
]"#;
let err = deser_json::Deserializer::from_str(input)
.deserialize_with::<Vec<Server>, _>(|driver| {
driver.state_mut().set_collect_errors(true)
})
.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`",
]
);Errors can also be collected for a whole deserialization by placing
CollectErrors in the context, which is how
this is usually configured from the outside.
Types can change this for the values in them, for instance to
collect the errors of a part of the input (and restore the previous
setting, see collect_errors, afterwards). 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 collect_errors(&self) -> bool
pub fn collect_errors(&self) -> bool
Returns true if maps and sequences are set to collect the errors
of their items (see set_collect_errors).
This is the setting, see collects_errors
for whether errors are collected at the moment.
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 declare_raw_format(
&mut self,
format: &'static RawFormatId,
) -> Option<&'static RawFormatInfo>
pub fn declare_raw_format( &mut self, format: &'static RawFormatId, ) -> Option<&'static RawFormatInfo>
Declares the format of the raw values that pass through as they are.
Formats with raw values (see Raw) call this with
the identity of their format:
- Deserializers call it before they emit the first event. Sinks
then request values that deserialize into raw values of the format
(see
Error::is_raw_request) and the format passes on their input asRawInputrather than their events. The top-level value is requested before the deserialization starts: if it’s wanted as raw value, this returns the description of the format the raw value wants, which the input is emitted with. Only the first call can return it. - Serializers call it before the first value and ignore the result.
Raw values of the format are then emitted as
RawInput, which the serializer writes as it is. Raw values of other formats are serialized as the values they hold.
Sourcepub fn take_raw_request(&mut self) -> Option<&'static RawFormatInfo>
pub fn take_raw_request(&mut self) -> Option<&'static RawFormatInfo>
Takes the description of the format of the raw value that the
result of an event requested (see Error::is_raw_request).
Formats emit the input of the value with it (see
RawInput::new): it’s the description
of their own format, but as it comes from the raw value the
functions of the format are only in programs that use its raw
values.
The description is not guaranteed to be the one of the caller’s
format: what is declared with
declare_raw_format can be changed by
everything that has access to the state, and descriptions can be
created with the identity of any format. Formats check its
id before they emit their input
with it.
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.
This is the value set in the state or, if there is none, the value
of the context. Returns None if neither has a
value of the type.
Sourcepub fn set_default<T: Default + Debug + Send + Sync + 'static>(
&mut self,
value: T,
)
pub fn set_default<T: Default + Debug + Send + Sync + 'static>( &mut self, value: T, )
Sets an extension value unless the state or the context has one.
Formats use this for their defaults of values that are configured
in the context, for instance query strings use the last of repeated
keys unless the context has a DuplicateKeys
policy.
Sourcepub fn context(&self) -> &Context
pub fn context(&self) -> &Context
Returns the context of the serialization or deserialization.
The context holds the configuration given from the outside, its
values are the defaults of the extension values (see
get).
Sourcepub fn set_context(&mut self, context: Context)
pub fn set_context(&mut self, context: Context)
Sets the context of the serialization or deserialization.
This replaces the context. The context is usually given to the
drivers (see
DeserializeDriver::set_context
and SerializeDriver::set_context),
which is typically done before the first event. Only the
DeserializeDriver enforces the
Limits of a context.
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 in the state, it’s initialized with the default value of the type (not the value of the context, which is hidden by the value of the state from then on).
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::set_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: &mut Error, state: &State) {
if err.attachment::<Depth>().is_none() {
err.set_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: &mut Error)
pub fn attach_error_context(&self, err: &mut 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 not changed.
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.