Skip to main content

State

Struct State 

Source
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 (get and get_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 (event and event_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

Source

pub fn new() -> State

Creates an empty state.

Drivers create their state, this is useful for code that processes events without a driver.

Source

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.

Source

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.

Source

pub fn collects_errors(&self) -> bool

Returns true if the errors of items are collected.

See set_collect_errors.

Source

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.

Source

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.

Source

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.

Source

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 as RawInput rather 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.
Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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).

Source

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.

Source

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_mut before they emit the event with the DeserializeDriver. The sinks that receive the event (including the finish of a container on its end event) can access it.
  • During serialization, Serialize implementations and emitters attach data while they produce a value. The format receives it together with the first event of the value from the SerializeDriver.

Event data is captured by a Recording and restored when the events are replayed.

Source

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);
}
Source

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)
}
Source

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).

Source

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.

Source

pub fn depth(&self) -> usize

Returns the current recursion depth.

This is the number of containers (maps and sequences) that are currently open.

Source

pub fn container_shape(&self) -> ContainerShape

Returns the shape of the container that is started.

During deserialization this is the shape of the MapStart or SeqStart event and is intended to be called from Sink::map and Sink::seq. At other times it’s the shape of the container that was started last.

Source

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.

Source

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.

Source

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.

Source

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);
Source

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);
Source

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.

Trait Implementations§

Source§

impl Debug for State

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for State

§

impl !UnwindSafe for State

§

impl Freeze for State

§

impl Send for State

§

impl Sync for State

§

impl Unpin for State

§

impl UnsafeUnpin for State

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.