Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/ron/src/de/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 34 kB image not shown  

SSL mod.rs

  Sprache: Rust
 

/// Deserialization module.
use alloc::{
    borrow::ToOwned,
    string::{String, ToString},
    vec::Vec,
};
use core::str;

use serde::{
    de::{self, DeserializeSeed, Deserializer as _, Visitor},
    Deserialize,
};

pub use crate::error::{Error, Position, Span, SpannedError};
use crate::{
    error::{Result, SpannedResult},
    extensions::Extensions,
    options::Options,
    parse::{NewtypeMode, ParsedByteStr, ParsedStr, Parser, StructType, TupleMode},
};

#[cfg(feature = "std")]
use std::io;

mod id;
mod tag;
#[cfg(test)]
mod tests;
mod value;

/// The RON deserializer.
///
/// If you just want to simply deserialize a value,
/// you can use the [`from_str`] convenience function.
pub struct Deserializer<'de> {
    pub(crate) parser: Parser<'de>,
    newtype_variant: bool,
    serde_content_newtype: bool,
    last_identifier: Option<&'de str>,
    recursion_limit: Option<usize>,
}

impl<'de> Deserializer<'de> {
    // Cannot implement trait here since output is tied to input lifetime 'de.
    #[allow(clippy::should_implement_trait)]
    pub fn from_str(input: &'de str) -> SpannedResult<Self> {
        Self::from_str_with_options(input, &Options::default())
    }

    pub fn from_bytes(input: &'de [u8]) -> SpannedResult<Self> {
        Self::from_bytes_with_options(input, &Options::default())
    }

    pub fn from_str_with_options(input: &'de str, options: &Options) -> SpannedResult<Self> {
        let mut deserializer = Deserializer {
            parser: Parser::new(input)?,
            newtype_variant: false,
            serde_content_newtype: false,
            last_identifier: None,
            recursion_limit: options.recursion_limit,
        };

        deserializer.parser.exts |= options.default_extensions;

        Ok(deserializer)
    }

    // FIXME: panic is not actually possible, remove once utf8_chunks is stabilized
    #[allow(clippy::missing_panics_doc)]
    pub fn from_bytes_with_options(input: &'de [u8], options: &Options) -> SpannedResult<Self> {
        let err = match str::from_utf8(input) {
            Ok(input) => return Self::from_str_with_options(input, options),
            Err(err) => err,
        };

        // FIXME: use [`utf8_chunks`](https://github.com/rust-lang/rust/issues/99543) once stabilised
        #[allow(clippy::expect_used)]
        let valid_input =
            str::from_utf8(&input[..err.valid_up_to()]).expect("source is valid up to error");

        Err(SpannedError {
            code: err.into(),
            span: Span {
                start: Position { line: 1, col: 1 },
                end: Position::from_src_end(valid_input),
            },
        })
    }

    #[must_use]
    pub fn remainder(&self) -> &'de str {
        self.parser.src()
    }

    #[must_use]
    pub fn span_error(&self, code: Error) -> SpannedError {
        self.parser.span_error(code)
    }

    #[must_use]
    pub fn extensions(&self) -> Extensions {
        self.parser.exts
    }
}

/// A convenience function for building a deserializer
/// and deserializing a value of type `T` from a reader.
#[cfg(feature = "std")]
pub fn from_reader<R, T>(rdr: R) -> SpannedResult<T>
where
    R: io::Read,
    T: de::DeserializeOwned,
{
    Options::default().from_reader(rdr)
}

/// A convenience function for building a deserializer
/// and deserializing a value of type `T` from a string.
pub fn from_str<'a, T>(s: &'a str) -> SpannedResult<T>
where
    T: de::Deserialize<'a>,
{
    Options::default().from_str(s)
}

/// A convenience function for building a deserializer
/// and deserializing a value of type `T` from bytes.
pub fn from_bytes<'a, T>(s: &'a [u8]) -> SpannedResult<T>
where
    T: de::Deserialize<'a>,
{
    Options::default().from_bytes(s)
}

macro_rules! guard_recursion {
    ($self:expr => $expr:expr) => {{
        if let Some(limit) = &mut $self.recursion_limit {
            if let Some(new_limit) = limit.checked_sub(1) {
                *limit = new_limit;
            } else {
                return Err(Error::ExceededRecursionLimit);
            }
        }

        let result = $expr;

        if let Some(limit) = &mut $self.recursion_limit {
            *limit = limit.saturating_add(1);
        }

        result
    }};
}

impl<'de> Deserializer<'de> {
    /// Check if the remaining bytes are whitespace only,
    /// otherwise return an error.
    pub fn end(&mut self) -> Result<()> {
        self.parser.skip_ws()?;

        if self.parser.src().is_empty() {
            Ok(())
        } else {
            Err(Error::TrailingCharacters)
        }
    }

    /// Called from [`deserialize_any`][serde::Deserializer::deserialize_any]
    /// when a struct was detected. Decides if there is a unit, tuple or usual
    /// struct and deserializes it accordingly.
    ///
    /// This method assumes there is no identifier left.
    fn handle_any_struct<V>(&mut self, visitor: V, ident: Option<&str>) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        // HACK: switch to JSON enum semantics for JSON content
        // Robust impl blocked on https://github.com/serde-rs/serde/issues/1183
        let is_serde_content =
            is_serde_content::<V::Value>() || is_serde_tag_or_content::<V::Value>();

        let old_serde_content_newtype = self.serde_content_newtype;
        self.serde_content_newtype = false;

        match (
            self.parser.check_struct_type(
                NewtypeMode::NoParensMeanUnit,
                if old_serde_content_newtype {
                    TupleMode::DifferentiateNewtype // separate match on NewtypeOrTuple below
                } else {
                    TupleMode::ImpreciseTupleOrNewtype // Tuple and NewtypeOrTuple match equally
                },
            )?,
            ident,
        ) {
            (StructType::Unit, Some(ident)) if is_serde_content => {
                // serde's Content type needs the ident for unit variants
                visitor.visit_str(ident)
            }
            (StructType::Unit, _) => visitor.visit_unit(),
            (_, Some(ident)) if is_serde_content => {
                // serde's Content type uses a singleton map encoding for enums
                visitor.visit_map(SerdeEnumContent {
                    de: self,
                    ident: Some(ident),
                })
            }
            (StructType::Named, _) => {
                // giving no name results in worse errors but is necessary here
                self.handle_struct_after_name("", visitor)
            }
            (StructType::NewtypeTuple, _) if old_serde_content_newtype => {
                // deserialize a newtype struct or variant
                self.parser.consume_char('(');
                self.parser.skip_ws()?;
                let result = self.deserialize_any(visitor);
                self.parser.skip_ws()?;
                self.parser.consume_char(')');

                result
            }
            (
                StructType::AnyTuple
                | StructType::EmptyTuple
                | StructType::NewtypeTuple
                | StructType::NonNewtypeTuple,
                _,
            ) => {
                // first argument is technically incorrect, but ignored anyway
                self.deserialize_tuple(0, visitor)
            }
        }
    }

    /// Called from
    /// [`deserialize_struct`][serde::Deserializer::deserialize_struct],
    /// [`struct_variant`][serde::de::VariantAccess::struct_variant], and
    /// [`handle_any_struct`][Self::handle_any_struct]. Handles
    /// deserialising the enclosing parentheses and everything in between.
    ///
    /// This method assumes there is no struct name identifier left.
    fn handle_struct_after_name<V>(
        &mut self,
        name_for_pretty_errors_only: &'static str,
        visitor: V,
    ) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.newtype_variant || self.parser.consume_char('(') {
            let old_newtype_variant = self.newtype_variant;
            self.newtype_variant = false;

            let value = guard_recursion! { self =>
                visitor
                    .visit_map(CommaSeparated::new(Terminator::Structself))
                    .map_err(|err| {
                        struct_error_name(
                            err,
                            if !old_newtype_variant && !name_for_pretty_errors_only.is_empty() {
                                Some(name_for_pretty_errors_only)
                            } else {
                                None
                            },
                        )
                    })?
            };

            self.parser.skip_ws()?;

            if old_newtype_variant || self.parser.consume_char(')') {
                Ok(value)
            } else {
                Err(Error::ExpectedStructLikeEnd)
            }
        } else if name_for_pretty_errors_only.is_empty() {
            Err(Error::ExpectedStructLike)
        } else {
            Err(Error::ExpectedNamedStructLike(name_for_pretty_errors_only))
        }
    }
}

impl<'de, 'a> de::Deserializer<'de> for &'mut Deserializer<'de> {
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.newtype_variant {
            if self.parser.check_char(')') {
                // newtype variant wraps the unit type / a unit struct without name
                return self.deserialize_unit(visitor);
            }

            #[allow(clippy::wildcard_in_or_patterns)]
            match self
                .parser
                .check_struct_type(NewtypeMode::InsideNewtype, TupleMode::DifferentiateNewtype)?
            {
                StructType::Named => {
                    // newtype variant wraps a named struct
                    // giving no name results in worse errors but is necessary here
                    return self.handle_struct_after_name("", visitor);
                }
                StructType::EmptyTuple | StructType::NonNewtypeTuple => {
                    // newtype variant wraps a tuple (struct)
                    // first argument is technically incorrect, but ignored anyway
                    return self.deserialize_tuple(0, visitor);
                }
                // StructType::Unit is impossible with NewtypeMode::InsideNewtype
                // StructType::AnyTuple is impossible with TupleMode::DifferentiateNewtype
                StructType::NewtypeTuple | _ => {
                    // continue as usual with the inner content of the newtype variant
                    self.newtype_variant = false;
                }
            }
        }

        if self.parser.consume_ident("true") {
            return visitor.visit_bool(true);
        } else if self.parser.consume_ident("false") {
            return visitor.visit_bool(false);
        } else if self.parser.check_ident("Some") {
            return self.deserialize_option(visitor);
        } else if self.parser.consume_ident("None") {
            return visitor.visit_none();
        } else if self.parser.consume_str("()") {
            return visitor.visit_unit();
        } else if self.parser.consume_ident("inf") || self.parser.consume_ident("inff32") {
            return visitor.visit_f32(core::f32::INFINITY);
        } else if self.parser.consume_ident("inff64") {
            return visitor.visit_f64(core::f64::INFINITY);
        } else if self.parser.consume_ident("NaN") || self.parser.consume_ident("NaNf32") {
            return visitor.visit_f32(core::f32::NAN);
        } else if self.parser.consume_ident("NaNf64") {
            return visitor.visit_f64(core::f64::NAN);
        }

        // `skip_identifier` does not change state if it fails
        if let Some(ident) = self.parser.skip_identifier() {
            self.parser.skip_ws()?;

            return self.handle_any_struct(visitor, Some(ident));
        }

        match self.parser.peek_char_or_eof()? {
            '(' => self.handle_any_struct(visitor, None),
            '[' => self.deserialize_seq(visitor),
            '{' => self.deserialize_map(visitor),
            '0'..='9' | '+' | '-' | '.' => self.parser.any_number()?.visit(visitor),
            '"' | 'r' => self.deserialize_string(visitor),
            'b' if self.parser.src().starts_with("b'") => self.parser.any_number()?.visit(visitor),
            'b' => self.deserialize_byte_buf(visitor),
            '\'' => self.deserialize_char(visitor),
            other => Err(Error::UnexpectedChar(other)),
        }
    }

    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_bool(self.parser.bool()?)
    }

    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_i8(self.parser.integer()?)
    }

    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_i16(self.parser.integer()?)
    }

    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_i32(self.parser.integer()?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_i64(self.parser.integer()?)
    }

    #[cfg(feature = "integer128")]
    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_i128(self.parser.integer()?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_u8(self.parser.integer()?)
    }

    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_u16(self.parser.integer()?)
    }

    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_u32(self.parser.integer()?)
    }

    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_u64(self.parser.integer()?)
    }

    #[cfg(feature = "integer128")]
    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_u128(self.parser.integer()?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_f32(self.parser.float()?)
    }

    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_f64(self.parser.float()?)
    }

    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_char(self.parser.char()?)
    }

    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        match self.parser.string()? {
            ParsedStr::Allocated(s) => visitor.visit_string(s),
            ParsedStr::Slice(s) => visitor.visit_borrowed_str(s),
        }
    }

    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_byte_buf(visitor)
    }

    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.parser.check_char('[') {
            let bytes = Vec::<u8>::deserialize(self)?;
            return visitor.visit_byte_buf(bytes);
        }

        match self.parser.byte_string()? {
            ParsedByteStr::Allocated(byte_buf) => visitor.visit_byte_buf(byte_buf),
            ParsedByteStr::Slice(bytes) => visitor.visit_borrowed_bytes(bytes),
        }
    }

    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.parser.consume_ident("None") {
            visitor.visit_none()
        } else if self.parser.consume_ident("Some") && {
            self.parser.skip_ws()?;
            self.parser.consume_char('(')
        } {
            self.parser.skip_ws()?;

            self.newtype_variant = self
                .parser
                .exts
                .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);

            let v = guard_recursion! { self => visitor.visit_some(&mut *self)? };

            self.newtype_variant = false;

            self.parser.comma()?;

            if self.parser.consume_char(')') {
                Ok(v)
            } else {
                Err(Error::ExpectedOptionEnd)
            }
        } else if self.parser.exts.contains(Extensions::IMPLICIT_SOME) {
            guard_recursion! { self => visitor.visit_some(&mut *self) }
        } else {
            Err(Error::ExpectedOption)
        }
    }

    // In Serde, unit means an anonymous value containing no data.
    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.newtype_variant || self.parser.consume_str("()") {
            self.newtype_variant = false;

            visitor.visit_unit()
        } else {
            Err(Error::ExpectedUnit)
        }
    }

    fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.newtype_variant || self.parser.consume_struct_name(name)? {
            self.newtype_variant = false;

            visitor.visit_unit()
        } else {
            self.deserialize_unit(visitor)
        }
    }

    fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if name == crate::value::raw::RAW_VALUE_TOKEN {
            let src_before = self.parser.pre_ws_src();
            self.parser.skip_ws()?;
            let _ignored = self.deserialize_ignored_any(de::IgnoredAny)?;
            self.parser.skip_ws()?;
            let src_after = self.parser.src();

            if self.parser.has_unclosed_line_comment() {
                return Err(Error::UnclosedLineComment);
            }

            let ron_str = &src_before[..src_before.len() - src_after.len()];

            return visitor
                .visit_borrowed_str::<Error>(ron_str)
                .map_err(|_| Error::ExpectedRawValue);
        }

        if self.parser.exts.contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
            self.newtype_variant = false;

            return guard_recursion! { self => visitor.visit_newtype_struct(&mut *self) };
        }

        self.parser.consume_struct_name(name)?;

        self.parser.skip_ws()?;

        if self.parser.consume_char('(') {
            self.parser.skip_ws()?;
            let value = guard_recursion! { self => visitor.visit_newtype_struct(&mut *self)? };
            self.parser.comma()?;

            if self.parser.consume_char(')') {
                Ok(value)
            } else {
                Err(Error::ExpectedStructLikeEnd)
            }
        } else if name.is_empty() {
            Err(Error::ExpectedStructLike)
        } else {
            Err(Error::ExpectedNamedStructLike(name))
        }
    }

    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.newtype_variant = false;

        if self.parser.consume_char('[') {
            let value = guard_recursion! { self =>
                visitor.visit_seq(CommaSeparated::new(Terminator::Seq, self))?
            };
            self.parser.skip_ws()?;

            if self.parser.consume_char(']') {
                Ok(value)
            } else {
                Err(Error::ExpectedArrayEnd)
            }
        } else {
            Err(Error::ExpectedArray)
        }
    }

    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if self.newtype_variant || self.parser.consume_char('(') {
            let old_newtype_variant = self.newtype_variant;
            self.newtype_variant = false;

            let value = guard_recursion! { self =>
                visitor.visit_seq(CommaSeparated::new(Terminator::Tuple, self))?
            };
            self.parser.skip_ws()?;

            if old_newtype_variant || self.parser.consume_char(')') {
                Ok(value)
            } else {
                Err(Error::ExpectedStructLikeEnd)
            }
        } else {
            Err(Error::ExpectedStructLike)
        }
    }

    fn deserialize_tuple_struct<V>(
        self,
        name: &'static str,
        len: usize,
        visitor: V,
    ) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if !self.newtype_variant {
            self.parser.consume_struct_name(name)?;
        }

        self.deserialize_tuple(len, visitor).map_err(|e| match e {
            Error::ExpectedStructLike if !name.is_empty() => Error::ExpectedNamedStructLike(name),
            e => e,
        })
    }

    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        struct VisitorExpecting<V>(V);
        impl<'de, V: Visitor<'de>> core::fmt::Display for VisitorExpecting<&>'_ V> {
            fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
                self.0.expecting(fmt)
            }
        }

        self.newtype_variant = false;

        // TODO: Avoid allocating to perform this check.
        let serde_flatten_canary = VisitorExpecting(&visitor)
            .to_string()
            .starts_with("struct ");

        let terminator = if serde_flatten_canary {
            Terminator::MapAsStruct
        } else {
            Terminator::Map
        };

        if self.parser.consume_char('{') {
            let value = guard_recursion! { self =>
                visitor.visit_map(CommaSeparated::new(terminator, self))?
            };
            self.parser.skip_ws()?;

            if self.parser.consume_char('}') {
                Ok(value)
            } else {
                Err(Error::ExpectedMapEnd)
            }
        } else {
            Err(Error::ExpectedMap)
        }
    }

    fn deserialize_struct<V>(
        self,
        name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        if !self.newtype_variant {
            self.parser.consume_struct_name(name)?;
        }

        self.parser.skip_ws()?;

        self.handle_struct_after_name(name, visitor)
    }

    fn deserialize_enum<V>(
        self,
        name: &'static str,
        _variants: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.newtype_variant = false;

        match guard_recursion! { self => visitor.visit_enum(Enum::new(self)) } {
            Ok(value) => Ok(value),
            Err(Error::NoSuchEnumVariant {
                expected,
                found,
                outer: None,
            }) if !name.is_empty() => Err(Error::NoSuchEnumVariant {
                expected,
                found,
                outer: Some(String::from(name)),
            }),
            Err(e) => Err(e),
        }
    }

    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        let identifier = self.parser.identifier()?;

        self.last_identifier = Some(identifier);

        visitor.visit_borrowed_str(identifier)
    }

    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_any(visitor)
    }
}

enum Terminator {
    Map,
    MapAsStruct,
    Tuple,
    Struct,
    Seq,
}

impl Terminator {
    fn as_char(&self) -> char {
        match self {
            Terminator::Map | Terminator::MapAsStruct => '}',
            Terminator::Tuple | Terminator::Struct => ')',
            Terminator::Seq => ']',
        }
    }
}

struct CommaSeparated<'a, 'de: 'a> {
    de: &'a mut Deserializer<'de>,
    terminator: Terminator,
    had_comma: bool,
    inside_internally_tagged_enum: bool,
}

impl<'a, 'de> CommaSeparated<'a, 'de> {
    fn new(terminator: Terminator, de: &'a mut Deserializer<'de>) -> Self {
        CommaSeparated {
            de,
            terminator,
            had_comma: true,
            inside_internally_tagged_enum: false,
        }
    }

    fn has_element(&mut self) -> Result<bool> {
        self.de.parser.skip_ws()?;

        match (
            self.had_comma,
            !self.de.parser.check_char(self.terminator.as_char()),
        ) {
            // Trailing comma, maybe has a next element
            (true, has_element) => Ok(has_element),
            // No trailing comma but terminator
            (falsefalse) => Ok(false),
            // No trailing comma or terminator
            (falsetrue) => Err(Error::ExpectedComma),
        }
    }
}

impl<'de, 'a> de::SeqAccess<'de> for CommaSeparated<'a, 'de> {
    type Error = Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        if self.has_element()? {
            let res = guard_recursion! { self.de => seed.deserialize(&mut *self.de)? };

            self.had_comma = self.de.parser.comma()?;

            Ok(Some(res))
        } else {
            Ok(None)
        }
    }
}

impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        if self.has_element()? {
            self.inside_internally_tagged_enum = is_serde_tag_or_content::<K::Value>();

            match self.terminator {
                Terminator::Struct => guard_recursion! { self.de =>
                    seed.deserialize(&mut id::Deserializer::new(&mut *self.de, false)).map(Some)
                },
                Terminator::MapAsStruct => guard_recursion! { self.de =>
                    seed.deserialize(&mut id::Deserializer::new(&mut *self.de, true)).map(Some)
                },
                _ => guard_recursion! { self.de => seed.deserialize(&mut *self.de).map(Some) },
            }
        } else {
            Ok(None)
        }
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        self.de.parser.skip_ws()?;

        if self.de.parser.consume_char(':') {
            self.de.parser.skip_ws()?;

            let res = if self.inside_internally_tagged_enum && !is_serde_content::<V::Value>() {
                guard_recursion! { self.de =>
                    seed.deserialize(&mut tag::Deserializer::new(&mut *self.de))?
                }
            } else {
                guard_recursion! { self.de =>
                    seed.deserialize(&mut *self.de)?
                }
            };

            self.had_comma = self.de.parser.comma()?;

            Ok(res)
        } else {
            Err(Error::ExpectedMapColon)
        }
    }
}

struct Enum<'a, 'de: 'a> {
    de: &'a mut Deserializer<'de>,
}

impl<'a, 'de> Enum<'a, 'de> {
    fn new(de: &'a mut Deserializer<'de>) -> Self {
        Enum { de }
    }
}

impl<'de, 'a> de::EnumAccess<'de> for Enum<'a, 'de> {
    type Error = Error;
    type Variant = Self;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
    where
        V: DeserializeSeed<'de>,
    {
        self.de.parser.skip_ws()?;

        let value = guard_recursion! { self.de => seed.deserialize(&mut *self.de)? };

        Ok((value, self))
    }
}

impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
    type Error = Error;

    fn unit_variant(self) -> Result<()> {
        Ok(())
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
    where
        T: DeserializeSeed<'de>,
    {
        let newtype_variant = self.de.last_identifier;

        self.de.parser.skip_ws()?;

        if self.de.parser.consume_char('(') {
            self.de.parser.skip_ws()?;

            self.de.newtype_variant = self
                .de
                .parser
                .exts
                .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);

            let val = guard_recursion! { self.de =>
                seed
                    .deserialize(&mut *self.de)
                    .map_err(|err| struct_error_name(err, newtype_variant))?
            };

            self.de.newtype_variant = false;

            self.de.parser.comma()?;

            if self.de.parser.consume_char(')') {
                Ok(val)
            } else {
                Err(Error::ExpectedStructLikeEnd)
            }
        } else {
            Err(Error::ExpectedStructLike)
        }
    }

    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        self.de.parser.skip_ws()?;

        self.de.deserialize_tuple(len, visitor)
    }

    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        let struct_variant = self.de.last_identifier;

        self.de.parser.skip_ws()?;

        self.de
            .handle_struct_after_name("", visitor)
            .map_err(|err| struct_error_name(err, struct_variant))
    }
}

fn struct_error_name(error: Error, name: Option<&str>) -> Error {
    match error {
        Error::NoSuchStructField {
            expected,
            found,
            outer: None,
        } => Error::NoSuchStructField {
            expected,
            found,
            outer: name.map(ToOwned::to_owned),
        },
        Error::MissingStructField { field, outer: None } => Error::MissingStructField {
            field,
            outer: name.map(ToOwned::to_owned),
        },
        Error::DuplicateStructField { field, outer: None } => Error::DuplicateStructField {
            field,
            outer: name.map(ToOwned::to_owned),
        },
        e => e,
    }
}

struct SerdeEnumContent<'a, 'de: 'a> {
    de: &'a mut Deserializer<'de>,
    ident: Option<&'a str>,
}

impl<'de, 'a> de::MapAccess<'de> for SerdeEnumContent<'a, 'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        self.ident
            .take()
            .map(|ident| seed.deserialize(de::value::StrDeserializer::new(ident)))
            .transpose()
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        self.de.parser.skip_ws()?;

        let old_serde_content_newtype = self.de.serde_content_newtype;
        self.de.serde_content_newtype = true;
        let result = seed.deserialize(&mut *self.de);
        self.de.serde_content_newtype = old_serde_content_newtype;

        result
    }
}

fn is_serde_content<T>() -> bool {
    #[derive(serde_derive::Deserialize)]
    enum A {}
    type B = A;

    #[derive(serde_derive::Deserialize)]
    #[serde(untagged)]
    enum UntaggedEnum {
        A(A),
        B(B),
    }

    struct TypeIdDeserializer;

    impl<'de> de::Deserializer<'de> for TypeIdDeserializer {
        type Error = TypeIdError;

        fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Self::Error> {
            Err(TypeIdError(typeid::of::<V::Value>()))
        }

        serde::forward_to_deserialize_any! {
            bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
            bytes byte_buf option unit unit_struct newtype_struct seq tuple
            tuple_struct map struct enum identifier ignored_any
        }
    }

    #[derive(Debug)]
    struct TypeIdError(core::any::TypeId);

    impl core::fmt::Display for TypeIdError {
        fn fmt(&self, _fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
            Ok(())
        }
    }

    impl de::Error for TypeIdError {
        #[allow(clippy::unreachable)]
        fn custom<T: core::fmt::Display>(_msg: T) -> Self {
            unreachable!()
        }
    }

    impl de::StdError for TypeIdError {}

    fn type_id_of_untagged_enum_default_buffer() -> core::any::TypeId {
        static TYPE_ID: once_cell::race::OnceBox<core::any::TypeId> =
            once_cell::race::OnceBox::new();

        *TYPE_ID.get_or_init(|| match Deserialize::deserialize(TypeIdDeserializer) {
            Ok(UntaggedEnum::A(void) | UntaggedEnum::B(void)) => match void {},
            Err(TypeIdError(typeid)) => alloc::boxed::Box::new(typeid),
        })
    }

    typeid::of::<T>() == type_id_of_untagged_enum_default_buffer()
}

fn is_serde_tag_or_content<T>() -> bool {
    #[derive(serde_derive::Deserialize)]
    enum A {}

    #[derive(serde_derive::Deserialize)]
    #[serde(tag = "tag")]
    enum InternallyTaggedEnum {
        A { a: A },
    }

    struct TypeIdDeserializer;

    impl<'de> de::Deserializer<'de> for TypeIdDeserializer {
        type Error = TypeIdError;

        fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
        where
            V: Visitor<'de>,
        {
            visitor.visit_map(self)
        }

        serde::forward_to_deserialize_any! {
            bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
            bytes byte_buf option unit unit_struct newtype_struct seq tuple
            tuple_struct map struct enum identifier ignored_any
        }
    }

    impl<'de> de::MapAccess<'de> for TypeIdDeserializer {
        type Error = TypeIdError;

        fn next_key_seed<K: DeserializeSeed<'de>>(
            &mut self,
            _seed: K,
        ) -> Result<Option<K::Value>, Self::Error> {
            Err(TypeIdError(typeid::of::<K::Value>()))
        }

        #[allow(clippy::unreachable)]
        fn next_value_seed<V: DeserializeSeed<'de>>(
            &mut self,
            _seed: V,
        ) -> Result<V::Value, Self::Error> {
            unreachable!()
        }
    }

    #[derive(Debug)]
    struct TypeIdError(core::any::TypeId);

    impl core::fmt::Display for TypeIdError {
        fn fmt(&self, _fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
            Ok(())
        }
    }

    impl de::Error for TypeIdError {
        #[allow(clippy::unreachable)]
        fn custom<T: core::fmt::Display>(_msg: T) -> Self {
            unreachable!()
        }
    }

    impl de::StdError for TypeIdError {}

    fn type_id_of_internally_tagged_enum_default_tag_or_buffer() -> core::any::TypeId {
        static TYPE_ID: once_cell::race::OnceBox<core::any::TypeId> =
            once_cell::race::OnceBox::new();

        *TYPE_ID.get_or_init(|| match Deserialize::deserialize(TypeIdDeserializer) {
            Ok(InternallyTaggedEnum::A { a: void }) => match void {},
            Err(TypeIdError(typeid)) => alloc::boxed::Box::new(typeid),
        })
    }

    typeid::of::<T>() == type_id_of_internally_tagged_enum_default_tag_or_buffer()
}

Messung V0.5 in Prozent
C=92 H=96 G=93

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.