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. pubstruct Deserializer<'de> {
bytes: Bytes<'de>,
newtype_variant: 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)] pubfn from_str(input: &'de str) -> SpannedResult<Self> { Self::from_str_with_options(input, Options::default())
}
/// A convenience function for building a deserializer /// and deserializing a value of type `T` from a reader. pubfn 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. pubfn 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. pubfn from_bytes<'a, T>(s: &'a [u8]) -> SpannedResult<T> where
T: de::Deserialize<'a>,
{
Options::default().from_bytes(s)
}
/// 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>(&mutself, visitor: V) -> Result<V::Value> where
V: Visitor<'de>,
{ // Create a working copy letmut bytes = self.bytes;
if bytes.consume("(") {
bytes.skip_ws()?;
if bytes.check_tuple_struct()? { // first argument is technically incorrect, but ignored anyway self.deserialize_tuple(0, visitor)
} else { // giving no name results in worse errors but is necessary here self.handle_struct_after_name("", visitor)
}
} else {
visitor.visit_unit()
}
}
/// 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>(
&mutself,
name_for_pretty_errors_only: &'static str,
visitor: V,
) -> Result<V::Value> where
V: Visitor<'de>,
{ ifself.newtype_variant || self.bytes.consume("(") { let old_newtype_variant = self.newtype_variant; self.newtype_variant = false;
let value = guard_recursion! { self =>
visitor
.visit_map(CommaSeparated::new(b')', self))
.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
},
)
})?
};
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> where
V: Visitor<'de>,
{ // Newtype variants can only be unwrapped if we receive information // about the wrapped type - with `deserialize_any` we don't self.newtype_variant = false;
let res = { let string = self.bytes.string()?; let base64_str = match string {
ParsedStr::Allocated(ref s) => s.as_str(),
ParsedStr::Slice(s) => s,
};
BASE64_ENGINE.decode(base64_str)
};
match res {
Ok(byte_buf) => visitor.visit_byte_buf(byte_buf),
Err(err) => Err(Error::Base64Error(err)),
}
}
// In Serde, unit means an anonymous value containing no data. fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where
V: Visitor<'de>,
{ ifself.newtype_variant || self.bytes.consume("()") { self.newtype_variant = false;
self.deserialize_tuple(len, visitor).map_err(|e| match e {
Error::ExpectedStructLike if !name.is_empty() => Error::ExpectedNamedStructLike(name),
e => e,
})
}
match ( self.had_comma, self.de.bytes.peek_or_eof()? != self.terminator,
) { // Trailing comma, maybe has a next element
(true, has_element) => Ok(has_element), // No trailing comma but terminator
(false, false) => Ok(false), // No trailing comma or terminator
(false, true) => Err(Error::ExpectedComma),
}
}
}
impl<'de, 'a> de::SeqAccess<'de> for CommaSeparated<'a, 'de> { type Error = Error;
fn next_element_seed<T>(&mutself, seed: T) -> Result<Option<T::Value>> where
T: DeserializeSeed<'de>,
{ ifself.has_element()? { let res = guard_recursion! { self.de => seed.deserialize(&mut *self.de)? };
self.had_comma = self.de.bytes.comma()?;
Ok(Some(res))
} else {
Ok(None)
}
}
}
impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> { type Error = Error;
¤ 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.0.13Bemerkung:
(vorverarbeitet am 2026-06-18)
¤
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.