Skip to main content

Deserializer

Struct Deserializer 

Source
pub struct Deserializer<'de, 'e> { /* private fields */ }
Expand description

The streaming Serde deserializer.

§Important: this deserializer borrows and is only available in a closure

YamlDeserializer borrows from the YAML input processing state, so you generally cannot construct and return it as a standalone value.

Instead, obtain it through the with_deserializer_from_* helpers, which provide a crate::Deserializer (an alias for YamlDeserializer) inside a closure.

This is useful when you want to wrap the deserializer (for example, to collect ignored fields or to add error context) while still deserializing into your target type.

§Example

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Config {
    host: String,
    port: u16,
}

let yaml = "host: localhost\nport: 8080\n";

let cfg: Config = serde_saphyr::with_deserializer_from_str(yaml,
    |de: serde_saphyr::Deserializer| {
        Config::deserialize(de)
})?;

assert_eq!(cfg.port, 8080);

This type is stateless with respect to ownership: it borrows the underlying input state ('e) and forwards Serde requests into it, translating YAML shapes into Serde calls.

Trait Implementations§

Source§

impl<'de> Deserializer<'de> for YamlDeserializer<'de, '_>

Source§

fn deserialize_any<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Fallback entry point when the caller’s type has no specific expectation.

When does Serde call this?

  • When the caller (Serde) does not know the exact Rust type to deserialize yet and wants the format to “do the best it can” from the data. This happens, for example, inside some enum deserialization strategies, in erased/typeless positions (e.g. Value-like seeds), or when visitor-based APIs defer the concrete type decision.
  • Even for structs/enums, Serde may call deserialize_any for individual field values when the driving logic cannot or does not specify a concrete numeric/bool/char method.

Can we force Serde to call the typed methods (deserialize_u8, deserialize_bool, …)?

  • Not from within a format Deserializer. Serde chooses which method to call based on the Rust type information it has via the caller’s Deserialize/DeserializeSeed logic. Implementing the typed methods (which we do) ensures Serde will use them whenever it knows the target type; otherwise, it falls back to deserialize_any.

Can we learn the target field’s Rust type from here?

  • No. Serde does not expose type reflection to Deserializers. The only hint we get is which method Serde chose to call. Field names are available in deserialize_struct, but not the field types.

Our policy:

  • Explicit core scalar tags and enabled robotics tags select the corresponding type regardless of scalar style. Plain, untagged scalars are inferred (null-like → bool → int → float) before falling back to string. Quoted scalars without a core type tag remain strings, and !!binary scalars are decoded as strings according to the configured binary-tag policy.

Flow: We inspect the next event; scalars are parsed with the heuristic above; containers delegate to deserialize_seq/deserialize_map.

Source§

fn deserialize_bool<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a boolean literal according to strict_booleans.

Caller: Serde when target expects bool. Flow: scalar text → Visitor::visit_bool.

Source§

fn deserialize_i8<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a signed 8-bit integer.

Source§

fn deserialize_i16<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a signed 16-bit integer.

Source§

fn deserialize_i32<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a signed 32-bit integer.

Source§

fn deserialize_i64<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a signed 64-bit integer.

Source§

fn deserialize_i128<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a signed 128-bit integer.

Source§

fn deserialize_u8<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse an unsigned 8-bit integer.

Source§

fn deserialize_u16<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse an unsigned 16-bit integer.

Source§

fn deserialize_u32<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse an unsigned 32-bit integer.

Source§

fn deserialize_u64<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse an unsigned 64-bit integer.

Source§

fn deserialize_u128<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse an unsigned 128-bit integer.

Source§

fn deserialize_f32<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a 32-bit float (supports YAML 1.2 +.inf, -.inf, .nan).

Source§

fn deserialize_f64<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a 64-bit float (supports YAML 1.2 +.inf, -.inf, .nan).

Source§

fn deserialize_char<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Parse a single Unicode scalar value (char).

Null semantics:

  • Tagged null or plain null-like scalars (empty, ~, null, Null, or NULL) are not valid char. Quoted forms are treated as normal strings and validated for length 1.
  • In no_schema mode, plain scalars that look like non-strings (numbers, bools, etc.) must be quoted; this check uses scalar style to avoid flagging quoted scalars.
Source§

fn deserialize_str<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a borrowed string.

When the scalar exists verbatim in the original input, this method uses Visitor::visit_borrowed_str.

Borrowing is only possible for in-memory inputs (e.g. from_str / from_slice) and only when no transformation is required (no escape processing, folding, chomping/indent handling, or multi-line normalization).

If borrowing is not possible, this method falls back to Visitor::visit_string. When the target type requires &str, that fallback produces a helpful error suggesting String or Cow<str>, with a TransformReason describing why borrowing was impossible.

Source§

fn deserialize_string<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize an owned string (with !!binary UTF-8 support).

Null semantics:

  • Tagged null or plain null-like scalars (empty, ~, null, Null, or NULL) are not valid String. Suggest using Option<String> for such YAML values.
  • Quoted “null” and quoted empty strings are treated as normal strings and allowed.

From/To: scalar text (or base64-decoded bytes) → Visitor::visit_string.

Source§

fn deserialize_bytes<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize bytes either from !!binary or from a sequence of integers (0..=255).

From/To:

  • Tagged scalar → base64-decoded Vec<u8> into Visitor::visit_byte_buf.
  • Sequence of integers → packed into Vec<u8> and visited.
Source§

fn deserialize_byte_buf<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize owned bytes; same semantics as deserialize_bytes.

Source§

fn deserialize_option<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize an Option<T>.

What is treated as None? End-of-input, container end, an explicitly tagged null, or a plain empty / ~ / null scalar permitting implicit null resolution. Explicit non-null core, binary, timestamp, and robotics tags are passed to the inner value’s deserializer.

Source§

fn deserialize_unit<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize the unit type ().

What is “unit” here? Rust’s () indicates “no value”. In Serde it commonly appears in unit structs/variants or fields intentionally ignored.
Accepted YAML forms: end-of-input, container end, or a null-like scalar in plain style ("", ~, null).

Source§

fn deserialize_unit_struct<V: Visitor<'de>>( self, _name: &'static str, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a unit struct.

Delegation: Struct unit forms are handled by allowing an empty mapping ({}) as the YAML representation, or by deferring to the same null-like forms accepted by deserialize_unit.
Visitor origin: Serde generates a visitor when deserializing the target unit struct type (via derive(Deserialize) or a manual impl). That visitor expects us to call Visitor::visit_unit.

Source§

fn deserialize_newtype_struct<V: Visitor<'de>>( self, n: &'static str, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a newtype struct (struct Wrapper(T);) by delegating to its inner value.

Why is this needed: Serde distinguishes newtype structs from their inner T so that attributes (like #[serde(transparent)]) and coherence rules are preserved. Even though YAML has no distinct “newtype” shape, Serde will invoke this method when the target is a newtype struct.
What do we do: Hand our own deserializer (self) to Visitor::visit_newtype_struct, which in turn will deserialize T using the same YAML event stream.

Source§

fn deserialize_seq<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a YAML sequence into a Serde sequence.

Flow: We provide a SeqAccess that repeatedly feeds nested Deser instances back into Serde for each element. Also supports a !!binary scalar as a byte sequence view when the caller expects a sequence of u8.

Source§

fn deserialize_tuple<V: Visitor<'de>>( self, len: usize, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a tuple; identical mechanics to sequences (fixed length checked by caller).

Source§

fn deserialize_tuple_struct<V: Visitor<'de>>( self, _name: &'static str, len: usize, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a tuple struct; identical mechanics to sequences.

Source§

fn deserialize_map<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a YAML mapping into a Serde map/struct field stream.

Flow: We expose a MapAccess implementation (MA) that:

  • Captures key/value nodes (able to replay them),
  • Applies duplicate-key policy,
  • Expands YAML merge keys (<<) in the correct precedence order.

Caller: Serde field visitors for maps and for Rust structs (which Serde also requests via deserialize_map).

Source§

fn deserialize_struct<V: Visitor<'de>>( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error>

Delegates struct deserialization to the same machinery as mappings.

Visitor origin: From Serde for the caller’s Rust struct type (usually generated by #[derive(Deserialize)]). That visitor expects a MapAccess yielding field names/values.
Where does it go? We call visitor.visit_map(..) via deserialize_map, which streams YAML mapping pairs as struct fields.

Source§

fn deserialize_enum<V: Visitor<'de>>( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize an externally-tagged enum in either Variant or { Variant: value } form.

Visitor origin: From Serde for the target enum type. Flow: We surface an EnumAccess (EA) that provides the variant name, and a VariantAccess (VA) that reads the payload (unit/newtype/tuple/struct).

Source§

fn deserialize_identifier<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize an identifier (e.g., struct field name); treated as string.

Source§

fn deserialize_ignored_any<V: Visitor<'de>>( self, visitor: V, ) -> Result<V::Value, Self::Error>

Deserialize a value that the caller intends to ignore.

Use the same tag validation and conversions as other untyped reads.

Source§

type Error = Error

The error type that can be returned if some error occurs during deserialization.
Source§

fn is_human_readable(&self) -> bool

Determine whether Deserialize implementations should expect to deserialize their human-readable form. Read more

Auto Trait Implementations§

§

impl<'de, 'e> !RefUnwindSafe for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> !Send for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> !Sync for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> !UnwindSafe for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> Freeze for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> Unpin for YamlDeserializer<'de, 'e>

§

impl<'de, 'e> UnsafeUnpin for YamlDeserializer<'de, 'e>

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.