Lines
46.74 %
Functions
66.52 %
Branches
100 %
use alloc::borrow::Cow;
use alloc::string::{String, ToString};
use core::fmt::Display;
use core::ops::Range;
use serde::de::{DeserializeOwned, EnumAccess, MapAccess, SeqAccess, VariantAccess};
use serde::Deserialize;
use crate::parser::{self, Config, Event, EventKind, Name, Nested, Parser, Primitive};
use crate::tokenizer::{self, Integer};
/// Deserializes Rsn using Serde.
pub struct Deserializer<'de> {
parser: BetterPeekable<Parser<'de>>,
newtype_state: Option<NewtypeState>,
}
#[derive(Clone, Copy, Eq, PartialEq)]
enum NewtypeState {
StructVariant,
TupleVariant,
impl<'de> Deserializer<'de> {
/// Returns a deserializer for `source` with the given `configuration`.
///
/// `Config::include_comments` will always be disabled, regardless of the
/// value set in `configuration`.
#[must_use]
pub fn new(source: &'de str, configuration: Config) -> Self {
Self {
parser: BetterPeekable::new(Parser::new(source, configuration.include_comments(false))),
newtype_state: None,
/// Checks that this deserializer has consumed all of the input.
/// # Errors
/// Returns [`parser::ErrorKind::TrailingData`] if there is any data left
/// unparsed.
pub fn ensure_eof(mut self) -> Result<(), Error> {
match self.parser.next() {
None => Ok(()),
Some(Ok(event)) => Err(Error::new(event.location, parser::ErrorKind::TrailingData)),
Some(Err(err)) => Err(Error::new(err.location, parser::ErrorKind::TrailingData)),
fn handle_unit(&mut self) -> Result<(), DeserializerError> {
self.with_error_context(|de| match de.parser.next().transpose()? {
Some(Event {
kind:
EventKind::BeginNested {
kind: Nested::Tuple,
..
},
}) => {
let mut nests = 1;
while nests > 0 {
match de.parser.next().transpose()? {
kind: EventKind::BeginNested { .. },
}) => nests += 1,
kind: EventKind::EndNested,
}) => nests -= 1,
Some(_) => {}
None => unreachable!("parser errors on early eof"),
Ok(())
Some(evt) => Err(DeserializerError::new(
evt.location,
ErrorKind::ExpectedUnit,
)),
None => Err(DeserializerError::new(None, ErrorKind::ExpectedUnit)),
})
fn with_error_context<T>(
&mut self,
f: impl FnOnce(&mut Self) -> Result<T, DeserializerError>,
) -> Result<T, DeserializerError> {
let error_start = self.parser.current_offset();
self.with_error_start(error_start, f)
fn with_error_start<T>(
error_start: usize,
match f(&mut *self) {
Ok(result) => Ok(result),
Err(mut err) => {
if err.location.is_none() {
err.location = Some(error_start..self.parser.current_offset());
Err(err)
fn set_newtype_state(&mut self, state: NewtypeState) -> NewtypeStateModification {
let old_state = self.newtype_state.replace(state);
NewtypeStateModification(old_state)
fn finish_newtype(&mut self, modification: NewtypeStateModification) -> Option<NewtypeState> {
core::mem::replace(&mut self.newtype_state, modification.0)
#[derive(Copy, Clone)]
struct NewtypeStateModification(Option<NewtypeState>);
macro_rules! deserialize_int_impl {
($de_name:ident, $visit_name:ident, $conv_name:ident) => {
fn $de_name<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
kind: EventKind::Primitive(Primitive::Integer(value)),
location,
}) => visitor.$visit_name(value.$conv_name().ok_or_else(|| {
DeserializerError::new(location, tokenizer::ErrorKind::IntegerTooLarge)
})?),
ErrorKind::ExpectedInteger,
None => Err(DeserializerError::new(None, ErrorKind::ExpectedInteger)),
};
impl<'de> serde::de::Deserializer<'de> for &mut Deserializer<'de> {
type Error = DeserializerError;
deserialize_int_impl!(deserialize_i8, visit_i8, as_i8);
deserialize_int_impl!(deserialize_i16, visit_i16, as_i16);
deserialize_int_impl!(deserialize_i32, visit_i32, as_i32);
deserialize_int_impl!(deserialize_i64, visit_i64, as_i64);
deserialize_int_impl!(deserialize_i128, visit_i128, as_i128);
deserialize_int_impl!(deserialize_u8, visit_u8, as_u8);
deserialize_int_impl!(deserialize_u16, visit_u16, as_u16);
deserialize_int_impl!(deserialize_u32, visit_u32, as_u32);
deserialize_int_impl!(deserialize_u64, visit_u64, as_u64);
deserialize_int_impl!(deserialize_u128, visit_u128, as_u128);
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.with_error_context(|de| {
let Some(event) = de.parser.next().transpose()? else {
return visitor.visit_unit();
match event.kind {
EventKind::BeginNested { name, kind } => match kind {
// Check for Some(), and ensure that this isn't a raw identifier
// by checking the original token's length.
Nested::Tuple
if name.as_deref() == Some("Some")
&& event.location.end - event.location.start == 4 =>
let value = visitor.visit_some(&mut *de)?;
let possible_close = de
.parser
.next()
.transpose()?
.expect("parser would error without EndNested");
match possible_close.kind {
EventKind::EndNested => Ok(value),
_ => Err(DeserializerError::new(
possible_close.location,
ErrorKind::SomeCanOnlyContainOneValue,
Nested::List | Nested::Tuple => {
if matches!(
de.parser.peek(),
Some(Ok(Event {
}))
) {
de.parser.next();
visitor.visit_unit()
} else {
visitor.visit_seq(sealed::SequenceDeserializer::new(de))
Nested::Map => visitor.visit_map(de),
EventKind::Primitive(primitive) => match primitive {
Primitive::Bool(v) => visitor.visit_bool(v),
Primitive::Integer(v) =>
#[allow(clippy::cast_possible_truncation)]
match v {
Integer::Usize(usize) => match usize::BITS {
0..=16 => visitor.visit_u16(usize as u16),
17..=32 => visitor.visit_u32(usize as u32),
33..=64 => visitor.visit_u64(usize as u64),
65..=128 => visitor.visit_u128(usize as u128),
_ => unreachable!("unsupported pointer width"),
Integer::Isize(isize) => match usize::BITS {
0..=16 => visitor.visit_i16(isize as i16),
17..=32 => visitor.visit_i32(isize as i32),
33..=64 => visitor.visit_i64(isize as i64),
65..=128 => visitor.visit_i128(isize as i128),
#[cfg(feature = "integer128")]
Integer::UnsignedLarge(large) => visitor.visit_u128(large),
#[cfg(not(feature = "integer128"))]
Integer::UnsignedLarge(large) => visitor.visit_u64(large),
Integer::SignedLarge(large) => visitor.visit_i128(large),
Integer::SignedLarge(large) => visitor.visit_i64(large),
Primitive::Float(v) => visitor.visit_f64(v),
Primitive::Char(v) => visitor.visit_char(v),
Primitive::String(v) => match v {
Cow::Borrowed(v) => visitor.visit_borrowed_str(v),
Cow::Owned(v) => visitor.visit_string(v),
Primitive::Identifier(v) => {
// The tokenizer will have tokenized `r#None` to `None`, so
// we must check the length of the original source to verify
// this isn't a raw identifier.
if v == "None" && event.location.end - event.location.start == 4 {
visitor.visit_none()
visitor.visit_borrowed_str(v)
Primitive::Bytes(v) => match v {
Cow::Borrowed(v) => visitor.visit_borrowed_bytes(v),
Cow::Owned(v) => visitor.visit_byte_buf(v),
EventKind::Comment(_) => unreachable!("comments are disabled"),
EventKind::EndNested => unreachable!("parser would error"),
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
kind: EventKind::Primitive(Primitive::Bool(value)),
}) => visitor.visit_bool(value),
}) => visitor.visit_bool(!value.is_zero()),
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.with_error_context(|de| de.deserialize_f64(visitor))
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
kind: EventKind::Primitive(Primitive::Float(value)),
}) => visitor.visit_f64(value),
}) => visitor.visit_f64(value.as_f64()),
ErrorKind::ExpectedFloat,
None => Err(DeserializerError::new(None, ErrorKind::ExpectedFloat)),
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
kind: EventKind::Primitive(Primitive::Char(value)),
}) => visitor.visit_char(value),
ErrorKind::ExpectedChar,
None => Err(DeserializerError::new(None, ErrorKind::ExpectedChar)),
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
kind: EventKind::Primitive(Primitive::Identifier(str)),
}) => visitor.visit_borrowed_str(str),
kind: EventKind::Primitive(Primitive::String(str)),
}) => match str {
Cow::Borrowed(str) => visitor.visit_borrowed_str(str),
Cow::Owned(str) => visitor.visit_string(str),
kind: EventKind::Primitive(Primitive::Bytes(bytes)),
}) => match bytes {
Cow::Borrowed(bytes) => visitor.visit_borrowed_str(
core::str::from_utf8(bytes)
.map_err(|_| DeserializerError::new(location, ErrorKind::InvalidUtf8))?,
),
Cow::Owned(bytes) => visitor.visit_string(
String::from_utf8(bytes)
name: Some(name), ..
}) => visitor.visit_str(name.name),
ErrorKind::ExpectedString,
None => Err(DeserializerError::new(None, ErrorKind::ExpectedString)),
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.with_error_context(|de| de.deserialize_str(visitor))
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
}) => visitor.visit_borrowed_bytes(str.as_bytes()),
Cow::Borrowed(str) => visitor.visit_borrowed_bytes(str.as_bytes()),
Cow::Owned(str) => visitor.visit_byte_buf(str.into_bytes()),
Cow::Borrowed(bytes) => visitor.visit_borrowed_bytes(bytes),
Cow::Owned(bytes) => visitor.visit_byte_buf(bytes),
ErrorKind::ExpectedBytes,
None => Err(DeserializerError::new(None, ErrorKind::ExpectedBytes)),
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.deserialize_bytes(visitor)
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.with_error_context(|de| match de.parser.peek() {
})) if *str == "None" => {
name: Some(Name { name: "Some", .. }),
})) => {
let result = visitor.visit_some(&mut *de)?;
}) => Ok(result),
None => Err(DeserializerError::new(None, ErrorKind::ExpectedOption)),
_ => visitor.visit_some(de),
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
self.handle_unit()?;
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
self.deserialize_unit(visitor)
fn deserialize_newtype_struct<V>(
name: &'static str,
self.deserialize_tuple_struct(name, 1, visitor)
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
kind: EventKind::BeginNested { kind, .. },
if !matches!(kind, Nested::Tuple | Nested::List) {
return Err(DeserializerError::new(
ErrorKind::ExpectedSequence,
));
de.with_error_context(|de| visitor.visit_seq(sealed::SequenceDeserializer::new(de)))
Some(other) => Err(DeserializerError::new(
other.location,
None => Err(DeserializerError::new(
None,
parser::ErrorKind::UnexpectedEof,
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
self.deserialize_seq(visitor)
fn deserialize_tuple_struct<V>(
struct_name: &'static str,
_len: usize,
let is_parsing_newtype_tuple =
matches!(self.newtype_state, Some(NewtypeState::TupleVariant));
let next_token_is_nested_tuple = matches!(
self.parser.peek(),
kind: EventKind::BeginNested {
);
if is_parsing_newtype_tuple {
if next_token_is_nested_tuple {
// We have a multi-nested newtype situation here, and to enable
// parsing the `)` easily, we need to "take over" by erasing the
// current newtype state.
return visitor.visit_seq(sealed::SequenceDeserializer::new(de));
kind: EventKind::BeginNested { name, kind },
if name.map_or(false, |name| name != struct_name) {
ErrorKind::NameMismatch(struct_name),
if kind != Nested::Tuple {
ErrorKind::ExpectedTupleStruct,
Some(other) => {
None => {
))
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
if kind != Nested::Map {
return Err(DeserializerError::new(location, ErrorKind::ExpectedMap));
visitor.visit_map(de)
ErrorKind::ExpectedMap,
fn deserialize_struct<V>(
_fields: &'static [&'static str],
if name.map_or(false, |name| name != struct_name)
&& !matches!(de.newtype_state, Some(NewtypeState::StructVariant))
ErrorKind::ExpectedMapStruct,
fn deserialize_enum<V>(
_variants: &'static [&'static str],
self.with_error_context(|de| visitor.visit_enum(de))
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
let mut depth = 0;
loop {
depth += 1;
depth -= 1;
kind: EventKind::Primitive(_) | EventKind::Comment(_),
}) => {}
if depth == 0 {
break;
impl<'de> MapAccess<'de> for Deserializer<'de> {
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
K: serde::de::DeserializeSeed<'de>,
Ok(None)
Some(Ok(evt)) => {
let error_start = evt.location.start;
de.with_error_start(error_start, |de| seed.deserialize(de).map(Some))
Some(_) => seed.deserialize(de).map(Some),
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
V: serde::de::DeserializeSeed<'de>,
seed.deserialize(&mut *self)
mod sealed {
use super::{
parser, Deserializer, DeserializerError, EnumAccess, ErrorKind, Event, EventKind, Nested,
NewtypeState, Primitive, SeqAccess, VariantAccess,
pub struct SequenceDeserializer<'a, 'de> {
de: &'a mut Deserializer<'de>,
ended: bool,
impl<'a, 'de> SequenceDeserializer<'a, 'de> {
pub(crate) fn new(de: &'a mut Deserializer<'de>) -> Self {
Self { de, ended: false }
impl<'a, 'de> SeqAccess<'de> for SequenceDeserializer<'a, 'de> {
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
T: serde::de::DeserializeSeed<'de>,
self.de.with_error_context(|de| match de.parser.peek() {
self.ended = true;
impl<'a, 'de> Drop for SequenceDeserializer<'a, 'de> {
fn drop(&mut self) {
if !self.ended {
let mut levels = 1;
if matches!(self.de.parser.peek(), None | Some(Err(_))) {
match self.de.parser.next().expect("just peeked") {
Ok(Event {
levels -= 1;
if levels == 0 {
levels += 1;
_ => {}
impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
type Variant = EnumVariantAccessor<'a, 'de>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
match self.parser.peek() {
kind: EventKind::Primitive(Primitive::Identifier(_) | Primitive::String(_)),
})) => Ok((seed.deserialize(&mut *self)?, EnumVariantAccessor::Unit)),
let variant = seed.deserialize(&mut VariantDeserializer(name))?;
Ok((variant, EnumVariantAccessor::Nested(self)))
_ => Err(DeserializerError::new(None, ErrorKind::ExpectedEnum)),
// match &self.0 {
// Value::Identifier(_) | Value::String(_) => {}
// Value::Named(named) => {
// let variant =
// seed.deserialize(ValueDeserializer(&Value::String(named.name.clone())))?;
// let accessor = match &named.contents {
// StructContents::Map(map) => EnumVariantAccessor::Map(map),
// StructContents::Tuple(list) => EnumVariantAccessor::Tuple(list),
// };
// Ok((variant, accessor))
// }
// _ => Err(FromValueError::Expected(ExpectedKind::Enum)),
struct VariantDeserializer<'a>(&'a str);
impl<'a, 'de> serde::Deserializer<'de> for &'a mut VariantDeserializer<'a> {
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
Err(DeserializerError::new(None, ErrorKind::ExpectedEnum))
fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
visitor.visit_str(self.0)
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
_visitor: V,
fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
pub enum EnumVariantAccessor<'a, 'de> {
Unit,
Nested(&'a mut Deserializer<'de>),
impl<'a, 'de> VariantAccess<'de> for EnumVariantAccessor<'a, 'de> {
fn unit_variant(self) -> Result<(), Self::Error> {
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
if let EnumVariantAccessor::Nested(deserializer) = self {
let modification = match deserializer.parser.peek() {
let _begin = deserializer.parser.next();
Some(deserializer.set_newtype_state(NewtypeState::TupleVariant))
kind: Nested::Map, ..
})) => Some(deserializer.set_newtype_state(NewtypeState::StructVariant)),
_ => None,
let result = deserializer.with_error_context(|de| seed.deserialize(&mut *de))?;
if let Some(modification) = modification {
if deserializer.finish_newtype(modification) == Some(NewtypeState::TupleVariant)
// SequenceDeserializer has a loop in its drop to eat the
// remaining events until the end
drop(SequenceDeserializer::new(&mut *deserializer));
Ok(result)
Err(DeserializerError::new(None, ErrorKind::ExpectedTupleStruct))
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
let nested_event = deserializer
.expect("variant access matched Nested")?;
deserializer.with_error_start(nested_event.location.start, |de| {
visitor.visit_seq(SequenceDeserializer::new(de))
fn struct_variant<V>(
deserializer
.with_error_start(nested_event.location.start, |de| visitor.visit_map(de))
/// A deserialization error.
#[derive(Debug, Clone, PartialEq)]
pub struct Error {
/// The offset of bytes in the source when the error occurred.
pub location: Range<usize>,
/// The kind of error that occurred.
pub kind: ErrorKind,
impl Error {
fn new(location: Range<usize>, kind: impl Into<ErrorKind>) -> Self {
kind: kind.into(),
impl From<parser::Error> for Error {
fn from(err: parser::Error) -> Self {
location: err.location,
kind: err.kind.into(),
impl serde::ser::StdError for Error {}
impl Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"{} at {}..{}",
self.kind, self.location.start, self.location.end
)
/// An error that arose while deserializing Rsn.
pub struct DeserializerError {
/// The location of the error, if available.
pub location: Option<Range<usize>>,
impl DeserializerError {
fn new(location: impl Into<Option<Range<usize>>>, kind: impl Into<ErrorKind>) -> Self {
location: location.into(),
impl serde::de::Error for DeserializerError {
fn custom<T>(msg: T) -> Self
T: Display,
location: None,
kind: ErrorKind::Message(msg.to_string()),
impl serde::ser::StdError for DeserializerError {}
impl Display for DeserializerError {
if let Some(location) = &self.location {
write!(f, "{} at {}..{}", self.kind, location.start, location.end)
Display::fmt(&self.kind, f)
impl From<parser::Error> for DeserializerError {
location: Some(err.location),
/// The kind of a deserialization error.
#[non_exhaustive]
pub enum ErrorKind {
/// An integer was expected.
ExpectedInteger,
/// A floating point number was expected.
ExpectedFloat,
/// A unit type was expected.
ExpectedUnit,
/// A boolean literal was expected.
ExpectedBool,
/// An option was expected.
ExpectedOption,
/// A character literal was expected.
ExpectedChar,
/// A string literal was expected.
ExpectedString,
/// A byte string literal was expected.
ExpectedBytes,
/// A sequence (list) was expected.
ExpectedSequence,
/// A map was expected.
ExpectedMap,
/// A structure containing a tuple was expected.
ExpectedTupleStruct,
/// A structure containing named fields was expected.
ExpectedMapStruct,
/// An enumerated value was expected.
ExpectedEnum,
/// Invalid UTF-8 was encountered in the input or while decoding escaped
/// characters.
InvalidUtf8,
/// The name of a type did not match what was expected.
/// The `&str` parameter is the name that was expected.
NameMismatch(&'static str),
/// `Some(_)` can only contain one value but more than one value was
/// encountered.
SomeCanOnlyContainOneValue,
/// An Rsn parsing error.
Parser(parser::ErrorKind),
/// An error from deserializing Serde.
Message(String),
impl From<parser::ErrorKind> for ErrorKind {
fn from(kind: parser::ErrorKind) -> Self {
Self::Parser(kind)
impl From<tokenizer::ErrorKind> for ErrorKind {
fn from(kind: tokenizer::ErrorKind) -> Self {
Self::Parser(kind.into())
impl Display for ErrorKind {
match self {
ErrorKind::Parser(parser) => Display::fmt(parser, f),
ErrorKind::Message(message) => f.write_str(message),
ErrorKind::ExpectedInteger => f.write_str("expected integer"),
ErrorKind::ExpectedFloat => f.write_str("expected float"),
ErrorKind::ExpectedBool => f.write_str("expected bool"),
ErrorKind::ExpectedUnit => f.write_str("expected unit"),
ErrorKind::ExpectedOption => f.write_str("expected option"),
ErrorKind::ExpectedChar => f.write_str("expected char"),
ErrorKind::ExpectedString => f.write_str("expected string"),
ErrorKind::ExpectedBytes => f.write_str("expected bytes"),
ErrorKind::SomeCanOnlyContainOneValue => {
f.write_str("Some(_) can only contain one value")
ErrorKind::ExpectedSequence => f.write_str("expected sequence"),
ErrorKind::ExpectedMap => f.write_str("expected map"),
ErrorKind::ExpectedTupleStruct => f.write_str("expected tuple struct"),
ErrorKind::ExpectedMapStruct => f.write_str("expected map struct"),
ErrorKind::ExpectedEnum => f.write_str("expected enum"),
ErrorKind::NameMismatch(name) => write!(f, "name mismatch, expected {name}"),
ErrorKind::InvalidUtf8 => f.write_str("invalid utf-8"),
impl Config {
/// Deserializes `T` from `source` using this configuration.
/// ```rust
/// let deserialized: Vec<usize> = rsn::parser::Config::default()
/// .deserialize("[1, 2, 3]")
/// .unwrap();
/// assert_eq!(deserialized, vec![1, 2, 3]);
/// ```
/// Returns an error if `source` cannot be deserialized as `T`.
pub fn deserialize<'de, T: Deserialize<'de>>(self, source: &'de str) -> Result<T, Error> {
let mut deserializer = Deserializer::new(source, self);
let result = match T::deserialize(&mut deserializer) {
Ok(result) => result,
Err(err) => {
let location = err
.location
.unwrap_or_else(|| deserializer.parser.current_range());
return Err(Error::new(location, err.kind));
deserializer.ensure_eof()?;
/// .deserialize_from_slice(b"[1, 2, 3]")
pub fn deserialize_from_slice<'de, T: Deserialize<'de>>(
source: &'de [u8],
) -> Result<T, Error> {
let source = match alloc::str::from_utf8(source) {
Ok(source) => source,
Err(error) => {
let end = error
.error_len()
.map_or(source.len(), |l| l + error.valid_up_to());
return Err(Error::new(
(error.valid_up_to() + 1)..end,
ErrorKind::InvalidUtf8,
self.deserialize(source)
/// Deserializes `T` from `reader` using this configuration.
/// .deserialize_from_reader(&b"[1, 2, 3]"[..])
/// Returns any errors encountered while reading from `reader` or if
/// `reader` cannot be deserialized as `T`.
#[cfg(feature = "std")]
pub fn deserialize_from_reader<T: DeserializeOwned, R: std::io::Read>(
mut reader: R,
let mut source = alloc::vec::Vec::new();
reader
.read_to_end(&mut source)
.map_err(|e| Error::new(0..0, ErrorKind::Message(e.to_string())))?;
self.deserialize_from_slice(&source)
struct BetterPeekable<T>
T: Iterator,
iter: T,
peeked: Option<T::Item>,
impl<T> BetterPeekable<T>
pub fn new(iter: T) -> Self {
Self { iter, peeked: None }
pub fn peek(&mut self) -> Option<&T::Item> {
if self.peeked.is_none() {
self.peeked = self.next();
self.peeked.as_ref()
impl<T> core::ops::Deref for BetterPeekable<T>
type Target = T;
fn deref(&self) -> &Self::Target {
&self.iter
impl<T> Iterator for BetterPeekable<T>
type Item = T::Item;
fn next(&mut self) -> Option<Self::Item> {
self.peeked.take().or_else(|| self.iter.next())
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use crate::parser::Config;
#[test]
fn basic_named() {
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
struct BasicNamed {
a: u32,
b: i32,
let parsed = crate::from_str::<BasicNamed>(r"BasicNamed{ a: 1, b: -1 }").unwrap();
assert_eq!(parsed, BasicNamed { a: 1, b: -1 });
fn implicit_map() {
let config = Config::default().allow_implicit_map_at_root(true);
let parsed = config.deserialize::<BasicNamed>("a: 1 b: -1").unwrap();
let parsed = config.deserialize::<BasicNamed>("a: 1, b: -1,").unwrap();
let parsed = config.deserialize::<BasicNamed>("{a: 1, b: -1}").unwrap();
let parsed = config
.deserialize::<BasicNamed>("BasicNamed{a: 1, b: -1}")
.unwrap();
fn optional() {
assert_eq!(crate::from_str::<Option<BasicNamed>>("None").unwrap(), None);
let parsed =
crate::from_str::<Option<BasicNamed>>("Some(BasicNamed{ a: 1, b: -1 })").unwrap();
assert_eq!(parsed, Some(BasicNamed { a: 1, b: -1 }));
let parsed = crate::from_str::<Option<BasicNamed>>("BasicNamed{ a: 1, b: -1 }").unwrap();
fn error_locality() {
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum Untagged {
A(#[allow(unused)] u64),
let source = r#"[1, "hello"]"#;
let err = crate::from_str::<alloc::vec::Vec<Untagged>>(source).unwrap_err();
assert_eq!(&source[err.location], r#""hello""#);
fn enums() {
enum BasicEnums {
NewType(u32),
Struct { a: u32 },
Tuple(u32, u32),
assert_eq!(
crate::from_str::<BasicEnums>("Unit").unwrap(),
BasicEnums::Unit
crate::from_str::<BasicEnums>("NewType(1)").unwrap(),
BasicEnums::NewType(1)
crate::from_str::<BasicEnums>("Struct{ a: 1}").unwrap(),
BasicEnums::Struct { a: 1 }
crate::from_str::<BasicEnums>("Tuple(1,2)").unwrap(),
BasicEnums::Tuple(1, 2)
crate::from_str::<BasicEnums>("Tuple(1,2,3)").unwrap(),