diff options
Diffstat (limited to 'third_party/rust/ron/src/de')
-rw-r--r-- | third_party/rust/ron/src/de/id.rs | 246 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/mod.rs | 807 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/tag.rs | 251 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/tests.rs | 362 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/value.rs | 335 |
5 files changed, 2001 insertions, 0 deletions
diff --git a/third_party/rust/ron/src/de/id.rs b/third_party/rust/ron/src/de/id.rs new file mode 100644 index 0000000000..537ce5690a --- /dev/null +++ b/third_party/rust/ron/src/de/id.rs @@ -0,0 +1,246 @@ +use serde::de::{self, Visitor}; + +use super::{Deserializer, Error, Result}; + +pub struct IdDeserializer<'a, 'b: 'a> { + d: &'a mut Deserializer<'b>, +} + +impl<'a, 'b: 'a> IdDeserializer<'a, 'b> { + pub fn new(d: &'a mut Deserializer<'b>) -> Self { + IdDeserializer { d } + } +} + +impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> { + type Error = Error; + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_identifier(visitor) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.deserialize_identifier(visitor) + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.deserialize_identifier(visitor) + } + + fn deserialize_bool<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_i8<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_i16<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_i32<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_i64<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + #[cfg(feature = "integer128")] + fn deserialize_i128<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_u8<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_u16<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_u32<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_u64<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + #[cfg(feature = "integer128")] + fn deserialize_u128<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_f32<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_f64<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_char<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_string<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_bytes<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_byte_buf<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_option<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_unit<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_unit_struct<V>(self, _: &'static str, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_newtype_struct<V>(self, _: &'static str, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_seq<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_tuple<V>(self, _: usize, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_map<V>(self, _: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_struct<V>( + self, + _: &'static str, + _: &'static [&'static str], + _: V, + ) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_enum<V>( + self, + _: &'static str, + _: &'static [&'static str], + _: V, + ) -> Result<V::Value> + where + V: Visitor<'b>, + { + unimplemented!("IdDeserializer may only be used for identifiers") + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.deserialize_any(visitor) + } +} diff --git a/third_party/rust/ron/src/de/mod.rs b/third_party/rust/ron/src/de/mod.rs new file mode 100644 index 0000000000..0920a67b43 --- /dev/null +++ b/third_party/rust/ron/src/de/mod.rs @@ -0,0 +1,807 @@ +/// Deserialization module. +pub use crate::error::{Error, Position, SpannedError}; + +use serde::de::{self, DeserializeSeed, Deserializer as SerdeError, Visitor}; +use std::{borrow::Cow, io, str}; + +use self::{id::IdDeserializer, tag::TagDeserializer}; +use crate::{ + error::{Result, SpannedResult}, + extensions::Extensions, + options::Options, + parse::{AnyNum, Bytes, ParsedStr}, +}; + +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> { + bytes: Bytes<'de>, + newtype_variant: bool, + last_identifier: Option<&'de str>, +} + +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> { + Self::from_bytes_with_options(input.as_bytes(), options) + } + + pub fn from_bytes_with_options(input: &'de [u8], options: Options) -> SpannedResult<Self> { + let mut deserializer = Deserializer { + bytes: Bytes::new(input)?, + newtype_variant: false, + last_identifier: None, + }; + + deserializer.bytes.exts |= options.default_extensions; + + Ok(deserializer) + } + + pub fn remainder(&self) -> Cow<'_, str> { + String::from_utf8_lossy(self.bytes.bytes()) + } + + pub fn span_error(&self, code: Error) -> SpannedError { + self.bytes.span_error(code) + } +} + +/// A convenience function for building a deserializer +/// and deserializing a value of type `T` from a reader. +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) +} + +impl<'de> Deserializer<'de> { + /// Check if the remaining bytes are whitespace only, + /// otherwise return an error. + pub fn end(&mut self) -> Result<()> { + self.bytes.skip_ws()?; + + if self.bytes.bytes().is_empty() { + Ok(()) + } else { + Err(Error::TrailingCharacters) + } + } + + /// Called from `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) -> Result<V::Value> + where + V: Visitor<'de>, + { + // Create a working copy + let mut 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 { + // first two arguments are technically incorrect, but ignored anyway + self.deserialize_struct("", &[], visitor) + } + } else { + visitor.visit_unit() + } + } +} + +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; + + if self.bytes.consume_ident("true") { + return visitor.visit_bool(true); + } else if self.bytes.consume_ident("false") { + return visitor.visit_bool(false); + } else if self.bytes.check_ident("Some") { + return self.deserialize_option(visitor); + } else if self.bytes.consume_ident("None") { + return visitor.visit_none(); + } else if self.bytes.consume("()") { + return visitor.visit_unit(); + } else if self.bytes.consume_ident("inf") { + return visitor.visit_f64(std::f64::INFINITY); + } else if self.bytes.consume_ident("-inf") { + return visitor.visit_f64(std::f64::NEG_INFINITY); + } else if self.bytes.consume_ident("NaN") { + return visitor.visit_f64(std::f64::NAN); + } + + // `identifier` does not change state if it fails + let ident = self.bytes.identifier().ok(); + + if ident.is_some() { + self.bytes.skip_ws()?; + + return self.handle_any_struct(visitor); + } + + match self.bytes.peek_or_eof()? { + b'(' => self.handle_any_struct(visitor), + b'[' => self.deserialize_seq(visitor), + b'{' => self.deserialize_map(visitor), + b'0'..=b'9' | b'+' | b'-' => { + let any_num: AnyNum = self.bytes.any_num()?; + + match any_num { + AnyNum::F32(x) => visitor.visit_f32(x), + AnyNum::F64(x) => visitor.visit_f64(x), + AnyNum::I8(x) => visitor.visit_i8(x), + AnyNum::U8(x) => visitor.visit_u8(x), + AnyNum::I16(x) => visitor.visit_i16(x), + AnyNum::U16(x) => visitor.visit_u16(x), + AnyNum::I32(x) => visitor.visit_i32(x), + AnyNum::U32(x) => visitor.visit_u32(x), + AnyNum::I64(x) => visitor.visit_i64(x), + AnyNum::U64(x) => visitor.visit_u64(x), + #[cfg(feature = "integer128")] + AnyNum::I128(x) => visitor.visit_i128(x), + #[cfg(feature = "integer128")] + AnyNum::U128(x) => visitor.visit_u128(x), + } + } + b'.' => self.deserialize_f64(visitor), + b'"' | b'r' => self.deserialize_string(visitor), + b'\'' => self.deserialize_char(visitor), + other => Err(Error::UnexpectedByte(other as char)), + } + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_bool(self.bytes.bool()?) + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_i8(self.bytes.signed_integer()?) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_i16(self.bytes.signed_integer()?) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_i32(self.bytes.signed_integer()?) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_i64(self.bytes.signed_integer()?) + } + + #[cfg(feature = "integer128")] + fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_i128(self.bytes.signed_integer()?) + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_u8(self.bytes.unsigned_integer()?) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_u16(self.bytes.unsigned_integer()?) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_u32(self.bytes.unsigned_integer()?) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_u64(self.bytes.unsigned_integer()?) + } + + #[cfg(feature = "integer128")] + fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_u128(self.bytes.unsigned_integer()?) + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_f32(self.bytes.float()?) + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_f64(self.bytes.float()?) + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_char(self.bytes.char()?) + } + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + match self.bytes.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>, + { + let res = { + let string = self.bytes.string()?; + let base64_str = match string { + ParsedStr::Allocated(ref s) => s.as_str(), + ParsedStr::Slice(s) => s, + }; + base64::decode(base64_str) + }; + + match res { + Ok(byte_buf) => visitor.visit_byte_buf(byte_buf), + Err(err) => Err(Error::Base64Error(err)), + } + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.bytes.consume("None") { + visitor.visit_none() + } else if self.bytes.consume("Some") && { + self.bytes.skip_ws()?; + self.bytes.consume("(") + } { + self.bytes.skip_ws()?; + + let v = visitor.visit_some(&mut *self)?; + + self.bytes.skip_ws()?; + + if self.bytes.consume(")") { + Ok(v) + } else { + Err(Error::ExpectedOptionEnd) + } + } else if self.bytes.exts.contains(Extensions::IMPLICIT_SOME) { + 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.bytes.consume("()") { + 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.bytes.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 self.bytes.exts.contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant { + self.newtype_variant = false; + + return visitor.visit_newtype_struct(&mut *self); + } + + self.bytes.consume_struct_name(name)?; + + self.bytes.skip_ws()?; + + if self.bytes.consume("(") { + self.bytes.skip_ws()?; + let value = visitor.visit_newtype_struct(&mut *self)?; + self.bytes.comma()?; + + if self.bytes.consume(")") { + Ok(value) + } else { + Err(Error::ExpectedStructLikeEnd) + } + } else if name.is_empty() { + Err(Error::ExpectedStructLike) + } else { + Err(Error::ExpectedNamedStructLike(name)) + } + } + + fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.newtype_variant = false; + + if self.bytes.consume("[") { + let value = visitor.visit_seq(CommaSeparated::new(b']', self))?; + self.bytes.comma()?; + + if self.bytes.consume("]") { + Ok(value) + } else { + Err(Error::ExpectedArrayEnd) + } + } else { + Err(Error::ExpectedArray) + } + } + + fn deserialize_tuple<V>(mut self, _len: usize, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.newtype_variant || self.bytes.consume("(") { + let old_newtype_variant = self.newtype_variant; + self.newtype_variant = false; + + let value = visitor.visit_seq(CommaSeparated::new(b')', self))?; + self.bytes.comma()?; + + if old_newtype_variant || self.bytes.consume(")") { + 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.bytes.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>(mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.newtype_variant = false; + + if self.bytes.consume("{") { + let value = visitor.visit_map(CommaSeparated::new(b'}', self))?; + self.bytes.comma()?; + + if self.bytes.consume("}") { + Ok(value) + } else { + Err(Error::ExpectedMapEnd) + } + } else { + Err(Error::ExpectedMap) + } + } + + fn deserialize_struct<V>( + mut self, + name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + if !self.newtype_variant { + self.bytes.consume_struct_name(name)?; + } + + self.bytes.skip_ws()?; + + if self.newtype_variant || self.bytes.consume("(") { + let old_newtype_variant = self.newtype_variant; + self.newtype_variant = false; + + let value = visitor + .visit_map(CommaSeparated::new(b')', self)) + .map_err(|err| { + struct_error_name( + err, + if !old_newtype_variant && !name.is_empty() { + Some(name) + } else { + None + }, + ) + })?; + + self.bytes.comma()?; + + if old_newtype_variant || self.bytes.consume(")") { + Ok(value) + } else { + Err(Error::ExpectedStructLikeEnd) + } + } else if name.is_empty() { + Err(Error::ExpectedStructLike) + } else { + Err(Error::ExpectedNamedStructLike(name)) + } + } + + 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 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 = str::from_utf8(self.bytes.identifier()?).map_err(Error::from)?; + + self.last_identifier = Some(identifier); + + visitor.visit_str(identifier) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } +} + +struct CommaSeparated<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, + terminator: u8, + had_comma: bool, +} + +impl<'a, 'de> CommaSeparated<'a, 'de> { + fn new(terminator: u8, de: &'a mut Deserializer<'de>) -> Self { + CommaSeparated { + de, + terminator, + had_comma: true, + } + } + + fn has_element(&mut self) -> Result<bool> { + self.de.bytes.skip_ws()?; + + 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>(&mut self, seed: T) -> Result<Option<T::Value>> + where + T: DeserializeSeed<'de>, + { + if self.has_element()? { + let res = 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; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>> + where + K: DeserializeSeed<'de>, + { + if self.has_element()? { + if self.terminator == b')' { + seed.deserialize(&mut IdDeserializer::new(&mut *self.de)) + .map(Some) + } else { + 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.bytes.skip_ws()?; + + if self.de.bytes.consume(":") { + self.de.bytes.skip_ws()?; + + let res = seed.deserialize(&mut TagDeserializer::new(&mut *self.de))?; + + self.had_comma = self.de.bytes.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.bytes.skip_ws()?; + + let value = 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.bytes.skip_ws()?; + + if self.de.bytes.consume("(") { + self.de.bytes.skip_ws()?; + + self.de.newtype_variant = self + .de + .bytes + .exts + .contains(Extensions::UNWRAP_VARIANT_NEWTYPES); + + let val = seed + .deserialize(&mut *self.de) + .map_err(|err| struct_error_name(err, newtype_variant))?; + + self.de.newtype_variant = false; + + self.de.bytes.comma()?; + + if self.de.bytes.consume(")") { + 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.bytes.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.bytes.skip_ws()?; + + self.de + .deserialize_struct("", fields, 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, + } +} diff --git a/third_party/rust/ron/src/de/tag.rs b/third_party/rust/ron/src/de/tag.rs new file mode 100644 index 0000000000..9e204ff847 --- /dev/null +++ b/third_party/rust/ron/src/de/tag.rs @@ -0,0 +1,251 @@ +use serde::de::{self, Visitor}; + +use super::{Deserializer, Error, Result}; + +pub struct TagDeserializer<'a, 'b: 'a> { + d: &'a mut Deserializer<'b>, +} + +impl<'a, 'b: 'a> TagDeserializer<'a, 'b> { + pub fn new(d: &'a mut Deserializer<'b>) -> Self { + TagDeserializer { d } + } +} + +impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> { + type Error = Error; + + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_str(visitor) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.deserialize_str(visitor) + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_any(visitor) + } + + fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_bool(visitor) + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_i8(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_i16(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_i32(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_i64(visitor) + } + + #[cfg(feature = "integer128")] + fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_i128(visitor) + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_u8(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_u16(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_u32(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_u64(visitor) + } + + #[cfg(feature = "integer128")] + fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_u128(visitor) + } + + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_f32(visitor) + } + + fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_f64(visitor) + } + + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_char(visitor) + } + + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_string(visitor) + } + + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_bytes(visitor) + } + + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_byte_buf(visitor) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_option(visitor) + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_unit(visitor) + } + + fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_unit_struct(name, visitor) + } + + fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_newtype_struct(name, visitor) + } + + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_seq(visitor) + } + + fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct<V>( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_tuple_struct(name, len, visitor) + } + + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_map(visitor) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_enum(name, variants, visitor) + } + + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'b>, + { + self.d.deserialize_ignored_any(visitor) + } +} diff --git a/third_party/rust/ron/src/de/tests.rs b/third_party/rust/ron/src/de/tests.rs new file mode 100644 index 0000000000..3e37e4e9db --- /dev/null +++ b/third_party/rust/ron/src/de/tests.rs @@ -0,0 +1,362 @@ +use serde::Deserialize; +use serde_bytes; + +use crate::{ + de::from_str, + error::{Error, Position, SpannedError, SpannedResult}, + parse::{AnyNum, Bytes}, +}; + +#[derive(Debug, PartialEq, Deserialize)] +struct EmptyStruct1; + +#[derive(Debug, PartialEq, Deserialize)] +struct EmptyStruct2 {} + +#[derive(Clone, Copy, Debug, PartialEq, Deserialize)] +struct MyStruct { + x: f32, + y: f32, +} + +#[derive(Clone, Copy, Debug, PartialEq, Deserialize)] +enum MyEnum { + A, + B(bool), + C(bool, f32), + D { a: i32, b: i32 }, +} + +#[derive(Debug, Deserialize, PartialEq)] +struct BytesStruct { + small: Vec<u8>, + #[serde(with = "serde_bytes")] + large: Vec<u8>, +} + +#[test] +fn test_empty_struct() { + assert_eq!(Ok(EmptyStruct1), from_str("EmptyStruct1")); + assert_eq!(Ok(EmptyStruct2 {}), from_str("EmptyStruct2()")); +} + +#[test] +fn test_struct() { + let my_struct = MyStruct { x: 4.0, y: 7.0 }; + + assert_eq!(Ok(my_struct), from_str("MyStruct(x:4,y:7,)")); + assert_eq!(Ok(my_struct), from_str("(x:4,y:7)")); + + #[derive(Debug, PartialEq, Deserialize)] + struct NewType(i32); + + assert_eq!(Ok(NewType(42)), from_str("NewType(42)")); + assert_eq!(Ok(NewType(33)), from_str("(33)")); + + #[derive(Debug, PartialEq, Deserialize)] + struct TupleStruct(f32, f32); + + assert_eq!(Ok(TupleStruct(2.0, 5.0)), from_str("TupleStruct(2,5,)")); + assert_eq!(Ok(TupleStruct(3.0, 4.0)), from_str("(3,4)")); +} + +#[test] +fn test_option() { + assert_eq!(Ok(Some(1u8)), from_str("Some(1)")); + assert_eq!(Ok(None::<u8>), from_str("None")); +} + +#[test] +fn test_enum() { + assert_eq!(Ok(MyEnum::A), from_str("A")); + assert_eq!(Ok(MyEnum::B(true)), from_str("B(true,)")); + assert_eq!(Ok(MyEnum::C(true, 3.5)), from_str("C(true,3.5,)")); + assert_eq!(Ok(MyEnum::D { a: 2, b: 3 }), from_str("D(a:2,b:3,)")); +} + +#[test] +fn test_array() { + let empty: [i32; 0] = []; + assert_eq!(Ok(empty), from_str("()")); + let empty_array = empty.to_vec(); + assert_eq!(Ok(empty_array), from_str("[]")); + + assert_eq!(Ok([2, 3, 4i32]), from_str("(2,3,4,)")); + assert_eq!(Ok([2, 3, 4i32].to_vec()), from_str("[2,3,4,]")); +} + +#[test] +fn test_map() { + use std::collections::HashMap; + + let mut map = HashMap::new(); + map.insert((true, false), 4); + map.insert((false, false), 123); + + assert_eq!( + Ok(map), + from_str( + "{ + (true,false,):4, + (false,false,):123, + }" + ) + ); +} + +#[test] +fn test_string() { + let s: String = from_str("\"String\"").unwrap(); + assert_eq!("String", s); + + let raw: String = from_str("r\"String\"").unwrap(); + assert_eq!("String", raw); + + let raw_hashes: String = from_str("r#\"String\"#").unwrap(); + assert_eq!("String", raw_hashes); + + let raw_hashes_multiline: String = from_str("r#\"String with\nmultiple\nlines\n\"#").unwrap(); + assert_eq!("String with\nmultiple\nlines\n", raw_hashes_multiline); + + let raw_hashes_quote: String = from_str("r##\"String with \"#\"##").unwrap(); + assert_eq!("String with \"#", raw_hashes_quote); +} + +#[test] +fn test_char() { + assert_eq!(Ok('c'), from_str("'c'")); +} + +#[test] +fn test_escape_char() { + assert_eq!('\'', from_str::<char>("'\\''").unwrap()); +} + +#[test] +fn test_escape() { + assert_eq!("\"Quoted\"", from_str::<String>(r#""\"Quoted\"""#).unwrap()); +} + +#[test] +fn test_comment() { + assert_eq!( + MyStruct { x: 1.0, y: 2.0 }, + from_str( + "( +x: 1.0, // x is just 1 +// There is another comment in the very next line.. +// And y is indeed +y: 2.0 // 2! + )" + ) + .unwrap() + ); +} + +fn err<T>(kind: Error, line: usize, col: usize) -> SpannedResult<T> { + Err(SpannedError { + code: kind, + position: Position { line, col }, + }) +} + +#[test] +fn test_err_wrong_value() { + use self::Error::*; + use std::collections::HashMap; + + assert_eq!(from_str::<f32>("'c'"), err(ExpectedFloat, 1, 1)); + assert_eq!(from_str::<String>("'c'"), err(ExpectedString, 1, 1)); + assert_eq!(from_str::<HashMap<u32, u32>>("'c'"), err(ExpectedMap, 1, 1)); + assert_eq!(from_str::<[u8; 5]>("'c'"), err(ExpectedStructLike, 1, 1)); + assert_eq!(from_str::<Vec<u32>>("'c'"), err(ExpectedArray, 1, 1)); + assert_eq!(from_str::<MyEnum>("'c'"), err(ExpectedIdentifier, 1, 1)); + assert_eq!( + from_str::<MyStruct>("'c'"), + err(ExpectedNamedStructLike("MyStruct"), 1, 1) + ); + assert_eq!( + from_str::<MyStruct>("NotMyStruct(x: 4, y: 2)"), + err( + ExpectedDifferentStructName { + expected: "MyStruct", + found: String::from("NotMyStruct") + }, + 1, + 12 + ) + ); + assert_eq!(from_str::<(u8, bool)>("'c'"), err(ExpectedStructLike, 1, 1)); + assert_eq!(from_str::<bool>("notabool"), err(ExpectedBoolean, 1, 1)); + + assert_eq!( + from_str::<MyStruct>("MyStruct(\n x: true)"), + err(ExpectedFloat, 2, 8) + ); + assert_eq!( + from_str::<MyStruct>("MyStruct(\n x: 3.5, \n y:)"), + err(ExpectedFloat, 3, 7) + ); +} + +#[test] +fn test_perm_ws() { + assert_eq!( + from_str::<MyStruct>("\nMyStruct \t ( \n x : 3.5 , \t y\n: 4.5 \n ) \t\n"), + Ok(MyStruct { x: 3.5, y: 4.5 }) + ); +} + +#[test] +fn untagged() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(untagged)] + enum Untagged { + U8(u8), + Bool(bool), + } + + assert_eq!(from_str::<Untagged>("true").unwrap(), Untagged::Bool(true)); + assert_eq!(from_str::<Untagged>("8").unwrap(), Untagged::U8(8)); +} + +#[test] +fn rename() { + #[derive(Deserialize, Debug, PartialEq)] + enum Foo { + #[serde(rename = "2d")] + D2, + #[serde(rename = "triangle-list")] + TriangleList, + } + assert_eq!(from_str::<Foo>("r#2d").unwrap(), Foo::D2); + assert_eq!( + from_str::<Foo>("r#triangle-list").unwrap(), + Foo::TriangleList + ); +} + +#[test] +fn forgot_apostrophes() { + let de: SpannedResult<(i32, String)> = from_str("(4, \"Hello)"); + + assert!(matches!( + de, + Err(SpannedError { + code: Error::ExpectedStringEnd, + position: _, + }) + )); +} + +#[test] +fn expected_attribute() { + let de: SpannedResult<String> = from_str("#\"Hello\""); + + assert_eq!(de, err(Error::ExpectedAttribute, 1, 2)); +} + +#[test] +fn expected_attribute_end() { + let de: SpannedResult<String> = from_str("#![enable(unwrap_newtypes) \"Hello\""); + + assert_eq!(de, err(Error::ExpectedAttributeEnd, 1, 28)); +} + +#[test] +fn invalid_attribute() { + let de: SpannedResult<String> = from_str("#![enable(invalid)] \"Hello\""); + + assert_eq!( + de, + err(Error::NoSuchExtension("invalid".to_string()), 1, 18) + ); +} + +#[test] +fn multiple_attributes() { + #[derive(Debug, Deserialize, PartialEq)] + struct New(String); + let de: SpannedResult<New> = + from_str("#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\""); + + assert_eq!(de, Ok(New("Hello".to_owned()))); +} + +#[test] +fn uglified_attribute() { + let de: SpannedResult<()> = from_str( + "# !\ + // We definitely want to add a comment here + [\t\tenable( // best style ever + unwrap_newtypes ) ] ()", + ); + + assert_eq!(de, Ok(())); +} + +#[test] +fn implicit_some() { + use serde::de::DeserializeOwned; + + fn de<T: DeserializeOwned>(s: &str) -> Option<T> { + let enable = "#![enable(implicit_some)]\n".to_string(); + + from_str::<Option<T>>(&(enable + s)).unwrap() + } + + assert_eq!(de("'c'"), Some('c')); + assert_eq!(de("5"), Some(5)); + assert_eq!(de("\"Hello\""), Some("Hello".to_owned())); + assert_eq!(de("false"), Some(false)); + assert_eq!( + de("MyStruct(x: .4, y: .5)"), + Some(MyStruct { x: 0.4, y: 0.5 }) + ); + + assert_eq!(de::<char>("None"), None); + + // Not concise + assert_eq!(de::<Option<Option<char>>>("None"), None); +} + +#[test] +fn ws_tuple_newtype_variant() { + assert_eq!(Ok(MyEnum::B(true)), from_str("B ( \n true \n ) ")); +} + +#[test] +fn test_byte_stream() { + assert_eq!( + Ok(BytesStruct { + small: vec![1, 2], + large: vec![1, 2, 3, 4] + }), + from_str("BytesStruct( small:[1, 2], large:\"AQIDBA==\" )"), + ); +} + +#[test] +fn test_numbers() { + assert_eq!( + Ok(vec![1234, 12345, 123456, 1234567, 555_555]), + from_str("[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]"), + ); +} + +fn de_any_number(s: &str) -> AnyNum { + let mut bytes = Bytes::new(s.as_bytes()).unwrap(); + + bytes.any_num().unwrap() +} + +#[test] +fn test_any_number_precision() { + assert_eq!(de_any_number("1"), AnyNum::U8(1)); + assert_eq!(de_any_number("+1"), AnyNum::I8(1)); + assert_eq!(de_any_number("-1"), AnyNum::I8(-1)); + assert_eq!(de_any_number("-1.0"), AnyNum::F32(-1.0)); + assert_eq!(de_any_number("1."), AnyNum::F32(1.)); + assert_eq!(de_any_number("-1."), AnyNum::F32(-1.)); + assert_eq!(de_any_number("0.3"), AnyNum::F64(0.3)); +} diff --git a/third_party/rust/ron/src/de/value.rs b/third_party/rust/ron/src/de/value.rs new file mode 100644 index 0000000000..544ee05e37 --- /dev/null +++ b/third_party/rust/ron/src/de/value.rs @@ -0,0 +1,335 @@ +use std::fmt; + +use serde::{ + de::{Error, MapAccess, SeqAccess, Visitor}, + Deserialize, Deserializer, +}; + +use crate::error::SpannedResult; +use crate::value::{Map, Number, Value}; + +impl std::str::FromStr for Value { + type Err = crate::error::SpannedError; + + /// Creates a value from a string reference. + fn from_str(s: &str) -> SpannedResult<Self> { + let mut de = super::Deserializer::from_str(s)?; + + let val = Value::deserialize(&mut de).map_err(|e| de.span_error(e))?; + de.end().map_err(|e| de.span_error(e))?; + + Ok(val) + } +} + +impl<'de> Deserialize<'de> for Value { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(ValueVisitor) + } +} + +struct ValueVisitor; + +impl<'de> Visitor<'de> for ValueVisitor { + type Value = Value; + + fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "a RON value") + } + + fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Bool(v)) + } + + fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Number(Number::new(v))) + } + + #[cfg(feature = "integer128")] + fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_f64(v as f64) + } + + fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Number(Number::new(v))) + } + + #[cfg(feature = "integer128")] + fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_f64(v as f64) + } + + fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Number(Number::new(v))) + } + + fn visit_char<E>(self, v: char) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Char(v)) + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_string(v.to_owned()) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::String(v)) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_byte_buf(v.to_vec()) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: Error, + { + self.visit_string(String::from_utf8(v).map_err(|e| Error::custom(format!("{}", e)))?) + } + + fn visit_none<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Option(None)) + } + + fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + Ok(Value::Option(Some(Box::new( + deserializer.deserialize_any(ValueVisitor)?, + )))) + } + + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(Value::Unit) + } + + fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(ValueVisitor) + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut vec = Vec::new(); + if let Some(cap) = seq.size_hint() { + vec.reserve_exact(cap); + } + + while let Some(x) = seq.next_element()? { + vec.push(x); + } + + Ok(Value::Seq(vec)) + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut res: Map = Map::new(); + + while let Some(entry) = map.next_entry()? { + res.insert(entry.0, entry.1); + } + + Ok(Value::Map(res)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + fn eval(s: &str) -> Value { + s.parse().expect("Failed to parse") + } + + #[test] + fn test_none() { + assert_eq!(eval("None"), Value::Option(None)); + } + + #[test] + fn test_some() { + assert_eq!(eval("Some(())"), Value::Option(Some(Box::new(Value::Unit)))); + assert_eq!( + eval("Some ( () )"), + Value::Option(Some(Box::new(Value::Unit))) + ); + } + + #[test] + fn test_tuples_basic() { + assert_eq!( + eval("(3, 4.0, 5.0)"), + Value::Seq(vec![ + Value::Number(Number::new(3)), + Value::Number(Number::new(4.0)), + Value::Number(Number::new(5.0)), + ],), + ); + } + + #[test] + fn test_tuples_ident() { + assert_eq!( + eval("(true, 3, 4, 5.0)"), + Value::Seq(vec![ + Value::Bool(true), + Value::Number(Number::new(3)), + Value::Number(Number::new(4)), + Value::Number(Number::new(5.0)), + ]), + ); + } + + #[test] + fn test_tuples_error() { + use crate::de::{Error, Position, SpannedError}; + + assert_eq!( + Value::from_str("Foo:").unwrap_err(), + SpannedError { + code: Error::TrailingCharacters, + position: Position { col: 4, line: 1 } + }, + ); + } + + #[test] + fn test_floats() { + assert_eq!( + eval("(inf, -inf, NaN)"), + Value::Seq(vec![ + Value::Number(Number::new(std::f64::INFINITY)), + Value::Number(Number::new(std::f64::NEG_INFINITY)), + Value::Number(Number::new(std::f64::NAN)), + ]), + ); + } + + #[test] + fn test_complex() { + assert_eq!( + eval( + "Some([ + Room ( width: 20, height: 5, name: \"The Room\" ), + + ( + width: 10.0, + height: 10.0, + name: \"Another room\", + enemy_levels: { + \"Enemy1\": 3, + \"Enemy2\": 5, + \"Enemy3\": 7, + }, + ), +])" + ), + Value::Option(Some(Box::new(Value::Seq(vec![ + Value::Map( + vec![ + ( + Value::String("width".to_owned()), + Value::Number(Number::new(20)), + ), + ( + Value::String("height".to_owned()), + Value::Number(Number::new(5)), + ), + ( + Value::String("name".to_owned()), + Value::String("The Room".to_owned()), + ), + ] + .into_iter() + .collect(), + ), + Value::Map( + vec![ + ( + Value::String("width".to_owned()), + Value::Number(Number::new(10.0)), + ), + ( + Value::String("height".to_owned()), + Value::Number(Number::new(10.0)), + ), + ( + Value::String("name".to_owned()), + Value::String("Another room".to_owned()), + ), + ( + Value::String("enemy_levels".to_owned()), + Value::Map( + vec![ + ( + Value::String("Enemy1".to_owned()), + Value::Number(Number::new(3)), + ), + ( + Value::String("Enemy2".to_owned()), + Value::Number(Number::new(5)), + ), + ( + Value::String("Enemy3".to_owned()), + Value::Number(Number::new(7)), + ), + ] + .into_iter() + .collect(), + ), + ), + ] + .into_iter() + .collect(), + ), + ])))) + ); + } +} |