diff options
Diffstat (limited to 'third_party/rust/ron/src')
-rw-r--r-- | third_party/rust/ron/src/de/id.rs | 244 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/mod.rs | 685 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/tag.rs | 249 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/tests.rs | 328 | ||||
-rw-r--r-- | third_party/rust/ron/src/de/value.rs | 335 | ||||
-rw-r--r-- | third_party/rust/ron/src/error.rs | 164 | ||||
-rw-r--r-- | third_party/rust/ron/src/extensions.rs | 26 | ||||
-rw-r--r-- | third_party/rust/ron/src/lib.rs | 75 | ||||
-rw-r--r-- | third_party/rust/ron/src/parse.rs | 932 | ||||
-rw-r--r-- | third_party/rust/ron/src/ser/mod.rs | 1089 | ||||
-rw-r--r-- | third_party/rust/ron/src/ser/value.rs | 23 | ||||
-rw-r--r-- | third_party/rust/ron/src/value.rs | 553 |
12 files changed, 4703 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..b8d7d59f87 --- /dev/null +++ b/third_party/rust/ron/src/de/id.rs @@ -0,0 +1,244 @@ +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") + } + + 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") + } + + 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..8c01d42a98 --- /dev/null +++ b/third_party/rust/ron/src/de/mod.rs @@ -0,0 +1,685 @@ +/// Deserialization module. +pub use crate::error::{Error, ErrorCode, Result}; +pub use crate::parse::Position; + +use serde::de::{self, DeserializeSeed, Deserializer as SerdeError, Visitor}; +use std::{borrow::Cow, io, str}; + +use self::{id::IdDeserializer, tag::TagDeserializer}; +use crate::{ + extensions::Extensions, + 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>, +} + +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) -> Result<Self> { + Deserializer::from_bytes(input.as_bytes()) + } + + pub fn from_bytes(input: &'de [u8]) -> Result<Self> { + Ok(Deserializer { + bytes: Bytes::new(input)?, + }) + } + + pub fn remainder(&self) -> Cow<'_, str> { + String::from_utf8_lossy(&self.bytes.bytes()) + } +} + +/// A convenience function for reading data from a reader +/// and feeding into a deserializer. +pub fn from_reader<R, T>(mut rdr: R) -> Result<T> +where + R: io::Read, + T: de::DeserializeOwned, +{ + let mut bytes = Vec::new(); + rdr.read_to_end(&mut bytes)?; + + from_bytes(&bytes) +} + +/// 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) -> Result<T> +where + T: de::Deserialize<'a>, +{ + from_bytes(s.as_bytes()) +} + +/// 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]) -> Result<T> +where + T: de::Deserialize<'a>, +{ + let mut deserializer = Deserializer::from_bytes(s)?; + let t = T::deserialize(&mut deserializer)?; + + deserializer.end()?; + + Ok(t) +} + +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 { + self.bytes.err(ErrorCode::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>, + { + 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), + AnyNum::I128(x) => visitor.visit_i128(x), + 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 => self.bytes.err(ErrorCode::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()?) + } + + 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()?) + } + + 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(ref s) => s, + }; + base64::decode(base64_str) + }; + + match res { + Ok(byte_buf) => visitor.visit_byte_buf(byte_buf), + Err(err) => self.bytes.err(ErrorCode::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.exts.contains(Extensions::IMPLICIT_SOME) { + visitor.visit_some(&mut *self) + } 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 { + self.bytes.err(ErrorCode::ExpectedOptionEnd) + } + } else { + self.bytes.err(ErrorCode::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.bytes.consume("()") { + visitor.visit_unit() + } else { + self.bytes.err(ErrorCode::ExpectedUnit) + } + } + + fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.bytes.consume(name) { + 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) { + return visitor.visit_newtype_struct(&mut *self); + } + + self.bytes.consume(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 { + self.bytes.err(ErrorCode::ExpectedStructEnd) + } + } else { + self.bytes.err(ErrorCode::ExpectedStruct) + } + } + + fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.bytes.consume("[") { + let value = visitor.visit_seq(CommaSeparated::new(b']', &mut self))?; + self.bytes.comma()?; + + if self.bytes.consume("]") { + Ok(value) + } else { + self.bytes.err(ErrorCode::ExpectedArrayEnd) + } + } else { + self.bytes.err(ErrorCode::ExpectedArray) + } + } + + fn deserialize_tuple<V>(mut self, _len: usize, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.bytes.consume("(") { + let value = visitor.visit_seq(CommaSeparated::new(b')', &mut self))?; + self.bytes.comma()?; + + if self.bytes.consume(")") { + Ok(value) + } else { + self.bytes.err(ErrorCode::ExpectedArrayEnd) + } + } else { + self.bytes.err(ErrorCode::ExpectedArray) + } + } + + fn deserialize_tuple_struct<V>( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.bytes.consume(name); + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + if self.bytes.consume("{") { + let value = visitor.visit_map(CommaSeparated::new(b'}', &mut self))?; + self.bytes.comma()?; + + if self.bytes.consume("}") { + Ok(value) + } else { + self.bytes.err(ErrorCode::ExpectedMapEnd) + } + } else { + self.bytes.err(ErrorCode::ExpectedMap) + } + } + + fn deserialize_struct<V>( + mut self, + name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.bytes.consume(name); + + self.bytes.skip_ws()?; + + if self.bytes.consume("(") { + let value = visitor.visit_map(CommaSeparated::new(b')', &mut self))?; + self.bytes.comma()?; + + if self.bytes.consume(")") { + Ok(value) + } else { + self.bytes.err(ErrorCode::ExpectedStructEnd) + } + } else { + self.bytes.err(ErrorCode::ExpectedStruct) + } + } + + fn deserialize_enum<V>( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_enum(Enum::new(self)) + } + + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + visitor.visit_str( + str::from_utf8(self.bytes.identifier()?).map_err(|e| self.bytes.error(e.into()))?, + ) + } + + 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 err<T>(&self, kind: ErrorCode) -> Result<T> { + self.de.bytes.err(kind) + } + + fn has_element(&mut self) -> Result<bool> { + self.de.bytes.skip_ws()?; + + Ok(self.had_comma && self.de.bytes.peek_or_eof()? != self.terminator) + } +} + +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 { + self.err(ErrorCode::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>, + { + self.de.bytes.skip_ws()?; + + if self.de.bytes.consume("(") { + self.de.bytes.skip_ws()?; + + let val = seed.deserialize(&mut *self.de)?; + + self.de.bytes.comma()?; + + if self.de.bytes.consume(")") { + Ok(val) + } else { + self.de.bytes.err(ErrorCode::ExpectedStructEnd) + } + } else { + self.de.bytes.err(ErrorCode::ExpectedStruct) + } + } + + 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>, + { + self.de.bytes.skip_ws()?; + + self.de.deserialize_struct("", fields, visitor) + } +} 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..76a8bb7973 --- /dev/null +++ b/third_party/rust/ron/src/de/tag.rs @@ -0,0 +1,249 @@ +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) + } + + 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) + } + + 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..f74b87b658 --- /dev/null +++ b/third_party/rust/ron/src/de/tests.rs @@ -0,0 +1,328 @@ +use serde::Deserialize; +use serde_bytes; + +use super::*; + +#[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: ErrorCode, line: usize, col: usize) -> Result<T> { + Err(Error { + code: kind, + position: Position { line, col }, + }) +} + +#[test] +fn test_err_wrong_value() { + use self::ErrorCode::*; + 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(ExpectedArray, 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(ExpectedStruct, 1, 1)); + assert_eq!(from_str::<(u8, bool)>("'c'"), err(ExpectedArray, 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 forgot_apostrophes() { + let de: Result<(i32, String)> = from_str("(4, \"Hello)"); + + assert!(match de { + Err(Error { + code: ErrorCode::ExpectedStringEnd, + position: _, + }) => true, + _ => false, + }); +} + +#[test] +fn expected_attribute() { + let de: Result<String> = from_str("#\"Hello\""); + + assert_eq!(de, err(ErrorCode::ExpectedAttribute, 1, 2)); +} + +#[test] +fn expected_attribute_end() { + let de: Result<String> = from_str("#![enable(unwrap_newtypes) \"Hello\""); + + assert_eq!(de, err(ErrorCode::ExpectedAttributeEnd, 1, 28)); +} + +#[test] +fn invalid_attribute() { + let de: Result<String> = from_str("#![enable(invalid)] \"Hello\""); + + assert_eq!( + de, + err(ErrorCode::NoSuchExtension("invalid".to_string()), 1, 18) + ); +} + +#[test] +fn multiple_attributes() { + #[derive(Debug, Deserialize, PartialEq)] + struct New(String); + let de: Result<New> = + from_str("#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\""); + + assert_eq!(de, Ok(New("Hello".to_owned()))); +} + +#[test] +fn uglified_attribute() { + let de: Result<()> = 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..92acca2068 --- /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::{ + de, + value::{Map, Number, Value}, +}; + +impl std::str::FromStr for Value { + type Err = de::Error; + + /// Creates a value from a string reference. + fn from_str(s: &str) -> de::Result<Self> { + let mut de = super::Deserializer::from_str(s)?; + + let val = Value::deserialize(&mut de)?; + de.end()?; + + 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))) + } + + 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))) + } + + 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, ErrorCode, Position}; + + assert_eq!( + Value::from_str("Foo:").unwrap_err(), + Error { + code: ErrorCode::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(), + ), + ])))) + ); + } +} diff --git a/third_party/rust/ron/src/error.rs b/third_party/rust/ron/src/error.rs new file mode 100644 index 0000000000..2a5052159a --- /dev/null +++ b/third_party/rust/ron/src/error.rs @@ -0,0 +1,164 @@ +use serde::{de, ser}; +use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; + +pub use crate::parse::Position; + +/// This type represents all possible errors that can occur when +/// serializing or deserializing RON data. +#[derive(Clone, Debug, PartialEq)] +pub struct Error { + pub code: ErrorCode, + pub position: Position, +} + +pub type Result<T> = std::result::Result<T, Error>; + +#[derive(Clone, Debug, PartialEq)] +pub enum ErrorCode { + Io(String), + Message(String), + Base64Error(base64::DecodeError), + Eof, + ExpectedArray, + ExpectedArrayEnd, + ExpectedAttribute, + ExpectedAttributeEnd, + ExpectedBoolean, + ExpectedComma, + // ExpectedEnum, + ExpectedChar, + ExpectedFloat, + ExpectedInteger, + ExpectedOption, + ExpectedOptionEnd, + ExpectedMap, + ExpectedMapColon, + ExpectedMapEnd, + ExpectedStruct, + ExpectedStructEnd, + ExpectedUnit, + // ExpectedStructName, + ExpectedString, + ExpectedStringEnd, + ExpectedIdentifier, + + InvalidEscape(&'static str), + + IntegerOutOfBounds, + + NoSuchExtension(String), + + UnclosedBlockComment, + UnderscoreAtBeginning, + UnexpectedByte(char), + + Utf8Error(Utf8Error), + TrailingCharacters, + + #[doc(hidden)] + __Nonexhaustive, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if (self.position == Position { line: 0, col: 0 }) { + write!(f, "{}", self.code) + } else { + write!(f, "{}: {}", self.position, self.code) + } + } +} + +impl fmt::Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ErrorCode::Io(ref s) => f.write_str(s), + ErrorCode::Message(ref s) => f.write_str(s), + ErrorCode::Base64Error(ref e) => fmt::Display::fmt(e, f), + ErrorCode::Eof => f.write_str("Unexpected end of file"), + ErrorCode::ExpectedArray => f.write_str("Expected array"), + ErrorCode::ExpectedArrayEnd => f.write_str("Expected end of array"), + ErrorCode::ExpectedAttribute => f.write_str("Expected an enable attribute"), + ErrorCode::ExpectedAttributeEnd => { + f.write_str("Expected closing `)` and `]` after the attribute") + } + ErrorCode::ExpectedBoolean => f.write_str("Expected boolean"), + ErrorCode::ExpectedComma => f.write_str("Expected comma"), + // ErrorCode::ExpectedEnum => f.write_str("Expected enum"), + ErrorCode::ExpectedChar => f.write_str("Expected char"), + ErrorCode::ExpectedFloat => f.write_str("Expected float"), + ErrorCode::ExpectedInteger => f.write_str("Expected integer"), + ErrorCode::ExpectedOption => f.write_str("Expected option"), + ErrorCode::ExpectedOptionEnd => f.write_str("Expected end of option"), + ErrorCode::ExpectedMap => f.write_str("Expected map"), + ErrorCode::ExpectedMapColon => f.write_str("Expected colon"), + ErrorCode::ExpectedMapEnd => f.write_str("Expected end of map"), + ErrorCode::ExpectedStruct => f.write_str("Expected struct"), + ErrorCode::ExpectedStructEnd => f.write_str("Expected end of struct"), + ErrorCode::ExpectedUnit => f.write_str("Expected unit"), + // ErrorCode::ExpectedStructName => f.write_str("Expected struct name"), + ErrorCode::ExpectedString => f.write_str("Expected string"), + ErrorCode::ExpectedStringEnd => f.write_str("Expected string end"), + ErrorCode::ExpectedIdentifier => f.write_str("Expected identifier"), + ErrorCode::InvalidEscape(_) => f.write_str("Invalid escape sequence"), + ErrorCode::IntegerOutOfBounds => f.write_str("Integer is out of bounds"), + ErrorCode::NoSuchExtension(_) => f.write_str("No such RON extension"), + ErrorCode::Utf8Error(ref e) => fmt::Display::fmt(e, f), + ErrorCode::UnclosedBlockComment => f.write_str("Unclosed block comment"), + ErrorCode::UnderscoreAtBeginning => f.write_str("Found underscore at the beginning"), + ErrorCode::UnexpectedByte(_) => f.write_str("Unexpected byte"), + ErrorCode::TrailingCharacters => f.write_str("Non-whitespace trailing characters"), + _ => f.write_str("Unknown ErrorCode"), + } + } +} + +impl de::Error for Error { + fn custom<T: fmt::Display>(msg: T) -> Self { + Error { + code: ErrorCode::Message(msg.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} + +impl ser::Error for Error { + fn custom<T: fmt::Display>(msg: T) -> Self { + Error { + code: ErrorCode::Message(msg.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} + +impl StdError for Error {} + +impl From<Utf8Error> for ErrorCode { + fn from(e: Utf8Error) -> Self { + ErrorCode::Utf8Error(e) + } +} + +impl From<FromUtf8Error> for ErrorCode { + fn from(e: FromUtf8Error) -> Self { + ErrorCode::Utf8Error(e.utf8_error()) + } +} + +impl From<Utf8Error> for Error { + fn from(e: Utf8Error) -> Self { + Error { + code: ErrorCode::Utf8Error(e), + position: Position { line: 0, col: 0 }, + } + } +} + +impl From<io::Error> for Error { + fn from(e: io::Error) -> Self { + Error { + code: ErrorCode::Io(e.to_string()), + position: Position { line: 0, col: 0 }, + } + } +} diff --git a/third_party/rust/ron/src/extensions.rs b/third_party/rust/ron/src/extensions.rs new file mode 100644 index 0000000000..5f3906c67d --- /dev/null +++ b/third_party/rust/ron/src/extensions.rs @@ -0,0 +1,26 @@ +use serde::{Deserialize, Serialize}; + +bitflags::bitflags! { + #[derive(Serialize, Deserialize)] + pub struct Extensions: usize { + const UNWRAP_NEWTYPES = 0x1; + const IMPLICIT_SOME = 0x2; + } +} + +impl Extensions { + /// Creates an extension flag from an ident. + pub fn from_ident(ident: &[u8]) -> Option<Extensions> { + match ident { + b"unwrap_newtypes" => Some(Extensions::UNWRAP_NEWTYPES), + b"implicit_some" => Some(Extensions::IMPLICIT_SOME), + _ => None, + } + } +} + +impl Default for Extensions { + fn default() -> Self { + Extensions::empty() + } +} diff --git a/third_party/rust/ron/src/lib.rs b/third_party/rust/ron/src/lib.rs new file mode 100644 index 0000000000..d9bf34ae5a --- /dev/null +++ b/third_party/rust/ron/src/lib.rs @@ -0,0 +1,75 @@ +/*! +RON is a simple config format which looks similar to Rust syntax. + +## Features + +* Data types + * Structs, typename optional + * Tuples + * Enums + * Lists + * Maps + * Units (`()`) + * Optionals + * Primitives: booleans, numbers, string, char +* Allows nested layout (similar to JSON) +* Supports comments +* Trailing commas +* Pretty serialization + +## Syntax example + +```rust,ignore +Game( + title: "Hello, RON!", + level: Level( // We could just leave the `Level` out + buildings: [ + ( + size: (10, 20), + color: Yellow, // This as an enum variant + owner: None, + ), + ( + size: (20, 25), + color: Custom(0.1, 0.8, 1.0), + owner: Some("guy"), + ), + ], + characters: { + "guy": ( + friendly: true, + ), + }, + ), +) +``` + +## Usage + +Just add it to your `Cargo.toml`: + +```toml +[dependencies] +ron = "*" +``` + +Serializing / Deserializing is as simple as calling `to_string` / `from_str`. + +!*/ + +#![doc(html_root_url = "https://docs.rs/ron/0.6.0")] + +pub mod de; +pub mod ser; + +pub mod error; +pub mod value; + +pub mod extensions; + +pub use de::{from_str, Deserializer}; +pub use error::{Error, Result}; +pub use ser::{to_string, Serializer}; +pub use value::{Map, Number, Value}; + +mod parse; diff --git a/third_party/rust/ron/src/parse.rs b/third_party/rust/ron/src/parse.rs new file mode 100644 index 0000000000..d592e44942 --- /dev/null +++ b/third_party/rust/ron/src/parse.rs @@ -0,0 +1,932 @@ +use std::{ + char::from_u32 as char_from_u32, + fmt::{Display, Formatter, Result as FmtResult}, + str::{from_utf8, from_utf8_unchecked, FromStr}, +}; + +use crate::{ + error::{Error, ErrorCode, Result}, + extensions::Extensions, +}; + +// We have the following char categories. +const INT_CHAR: u8 = 1 << 0; // [0-9A-Fa-f_] +const FLOAT_CHAR: u8 = 1 << 1; // [0-9\.Ee+-] +const IDENT_FIRST_CHAR: u8 = 1 << 2; // [A-Za-z_] +const IDENT_OTHER_CHAR: u8 = 1 << 3; // [A-Za-z_0-9] +const WHITESPACE_CHAR: u8 = 1 << 4; // [\n\t\r ] + +// We encode each char as belonging to some number of these categories. +const DIGIT: u8 = INT_CHAR | FLOAT_CHAR | IDENT_OTHER_CHAR; // [0-9] +const ABCDF: u8 = INT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR; // [ABCDFabcdf] +const UNDER: u8 = INT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR; // [_] +const E____: u8 = INT_CHAR | FLOAT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR; // [Ee] +const G2Z__: u8 = IDENT_FIRST_CHAR | IDENT_OTHER_CHAR; // [G-Zg-z] +const PUNCT: u8 = FLOAT_CHAR; // [\.+-] +const WS___: u8 = WHITESPACE_CHAR; // [\t\n\r ] +const _____: u8 = 0; // everything else + +// Table of encodings, for fast predicates. (Non-ASCII and special chars are +// shown with '·' in the comment.) +#[rustfmt::skip] +const ENCODINGS: [u8; 256] = [ +/* 0 1 2 3 4 5 6 7 8 9 */ +/* 0+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, WS___, +/* 10+: ·········· */ WS___, _____, _____, WS___, _____, _____, _____, _____, _____, _____, +/* 20+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 30+: ·· !"#$%&' */ _____, _____, WS___, _____, _____, _____, _____, _____, _____, _____, +/* 40+: ()*+,-./01 */ _____, _____, _____, PUNCT, _____, PUNCT, PUNCT, _____, DIGIT, DIGIT, +/* 50+: 23456789:; */ DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, _____, _____, +/* 60+: <=>?@ABCDE */ _____, _____, _____, _____, _____, ABCDF, ABCDF, ABCDF, ABCDF, E____, +/* 70+: FGHIJKLMNO */ ABCDF, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, +/* 80+: PQRSTUVWZY */ G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, +/* 90+: Z[\]^_`abc */ G2Z__, _____, _____, _____, _____, UNDER, _____, ABCDF, ABCDF, ABCDF, +/* 100+: defghijklm */ ABCDF, E____, ABCDF, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, +/* 110+: nopqrstuvw */ G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, G2Z__, +/* 120+: xyz{|}~··· */ G2Z__, G2Z__, G2Z__, _____, _____, _____, _____, _____, _____, _____, +/* 130+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 140+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 150+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 160+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 170+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 180+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 190+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 200+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 210+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 220+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 230+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 240+: ·········· */ _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, +/* 250+: ·········· */ _____, _____, _____, _____, _____, _____ +]; + +const fn is_int_char(c: u8) -> bool { + ENCODINGS[c as usize] & INT_CHAR != 0 +} + +const fn is_float_char(c: u8) -> bool { + ENCODINGS[c as usize] & FLOAT_CHAR != 0 +} + +const fn is_ident_first_char(c: u8) -> bool { + ENCODINGS[c as usize] & IDENT_FIRST_CHAR != 0 +} + +const fn is_ident_other_char(c: u8) -> bool { + ENCODINGS[c as usize] & IDENT_OTHER_CHAR != 0 +} + +const fn is_whitespace_char(c: u8) -> bool { + ENCODINGS[c as usize] & WHITESPACE_CHAR != 0 +} + +#[derive(Clone, Debug, PartialEq)] +pub enum AnyNum { + F32(f32), + F64(f64), + I8(i8), + U8(u8), + I16(i16), + U16(u16), + I32(i32), + U32(u32), + I64(i64), + U64(u64), + I128(i128), + U128(u128), +} + +#[derive(Clone, Copy, Debug)] +pub struct Bytes<'a> { + /// Bits set according to `Extension` enum. + pub exts: Extensions, + bytes: &'a [u8], + column: usize, + line: usize, +} + +impl<'a> Bytes<'a> { + pub fn new(bytes: &'a [u8]) -> Result<Self> { + let mut b = Bytes { + bytes, + column: 1, + exts: Extensions::empty(), + line: 1, + }; + + b.skip_ws()?; + // Loop over all extensions attributes + loop { + let attribute = b.extensions()?; + + if attribute.is_empty() { + break; + } + + b.exts |= attribute; + b.skip_ws()?; + } + + Ok(b) + } + + pub fn advance(&mut self, bytes: usize) -> Result<()> { + for _ in 0..bytes { + self.advance_single()?; + } + + Ok(()) + } + + pub fn advance_single(&mut self) -> Result<()> { + if self.peek_or_eof()? == b'\n' { + self.line += 1; + self.column = 1; + } else { + self.column += 1; + } + + self.bytes = &self.bytes[1..]; + + Ok(()) + } + + fn any_integer<T: Num>(&mut self, sign: i8) -> Result<T> { + let base = if self.peek() == Some(b'0') { + match self.bytes.get(1).cloned() { + Some(b'x') => 16, + Some(b'b') => 2, + Some(b'o') => 8, + _ => 10, + } + } else { + 10 + }; + + if base != 10 { + // If we have `0x45A` for example, + // cut it to `45A`. + let _ = self.advance(2); + } + + let num_bytes = self.next_bytes_contained_in(is_int_char); + + if num_bytes == 0 { + return self.err(ErrorCode::ExpectedInteger); + } + + let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) }; + + if s.as_bytes()[0] == b'_' { + return self.err(ErrorCode::UnderscoreAtBeginning); + } + + fn calc_num<T: Num>( + bytes: &Bytes, + s: &str, + base: u8, + mut f: impl FnMut(&mut T, u8) -> bool, + ) -> Result<T> { + let mut num_acc = T::from_u8(0); + + for &byte in s.as_bytes() { + if byte == b'_' { + continue; + } + + if num_acc.checked_mul_ext(base) { + return bytes.err(ErrorCode::IntegerOutOfBounds); + } + + let digit = bytes.decode_hex(byte)?; + + if digit >= base { + return bytes.err(ErrorCode::ExpectedInteger); + } + + if f(&mut num_acc, digit) { + return bytes.err(ErrorCode::IntegerOutOfBounds); + } + } + + Ok(num_acc) + }; + + let res = if sign > 0 { + calc_num(&*self, s, base, T::checked_add_ext) + } else { + calc_num(&*self, s, base, T::checked_sub_ext) + }; + + let _ = self.advance(num_bytes); + + res + } + + pub fn any_num(&mut self) -> Result<AnyNum> { + // We are not doing float comparisons here in the traditional sense. + // Instead, this code checks if a f64 fits inside an f32. + #[allow(clippy::float_cmp)] + fn any_float(f: f64) -> Result<AnyNum> { + if f == f as f32 as f64 { + Ok(AnyNum::F32(f as f32)) + } else { + Ok(AnyNum::F64(f)) + } + } + + let bytes_backup = self.bytes; + + let first_byte = self.peek_or_eof()?; + let is_signed = first_byte == b'-' || first_byte == b'+'; + let is_float = self.next_bytes_is_float(); + + if is_float { + let f = self.float::<f64>()?; + + any_float(f) + } else { + let max_u8 = std::u8::MAX as u128; + let max_u16 = std::u16::MAX as u128; + let max_u32 = std::u32::MAX as u128; + let max_u64 = std::u64::MAX as u128; + + let min_i8 = std::i8::MIN as i128; + let max_i8 = std::i8::MAX as i128; + let min_i16 = std::i16::MIN as i128; + let max_i16 = std::i16::MAX as i128; + let min_i32 = std::i32::MIN as i128; + let max_i32 = std::i32::MAX as i128; + let min_i64 = std::i64::MIN as i128; + let max_i64 = std::i64::MAX as i128; + + if is_signed { + match self.signed_integer::<i128>() { + Ok(x) => { + if x >= min_i8 && x <= max_i8 { + Ok(AnyNum::I8(x as i8)) + } else if x >= min_i16 && x <= max_i16 { + Ok(AnyNum::I16(x as i16)) + } else if x >= min_i32 && x <= max_i32 { + Ok(AnyNum::I32(x as i32)) + } else if x >= min_i64 && x <= max_i64 { + Ok(AnyNum::I64(x as i64)) + } else { + Ok(AnyNum::I128(x)) + } + } + Err(_) => { + self.bytes = bytes_backup; + + any_float(self.float::<f64>()?) + } + } + } else { + match self.unsigned_integer::<u128>() { + Ok(x) => { + if x <= max_u8 { + Ok(AnyNum::U8(x as u8)) + } else if x <= max_u16 { + Ok(AnyNum::U16(x as u16)) + } else if x <= max_u32 { + Ok(AnyNum::U32(x as u32)) + } else if x <= max_u64 { + Ok(AnyNum::U64(x as u64)) + } else { + Ok(AnyNum::U128(x)) + } + } + Err(_) => { + self.bytes = bytes_backup; + + any_float(self.float::<f64>()?) + } + } + } + } + } + + pub fn bool(&mut self) -> Result<bool> { + if self.consume("true") { + Ok(true) + } else if self.consume("false") { + Ok(false) + } else { + self.err(ErrorCode::ExpectedBoolean) + } + } + + pub fn bytes(&self) -> &[u8] { + &self.bytes + } + + pub fn char(&mut self) -> Result<char> { + if !self.consume("'") { + return self.err(ErrorCode::ExpectedChar); + } + + let c = self.peek_or_eof()?; + + let c = if c == b'\\' { + let _ = self.advance(1); + + self.parse_escape()? + } else { + // Check where the end of the char (') is and try to + // interpret the rest as UTF-8 + + let max = self.bytes.len().min(5); + let pos: usize = self.bytes[..max] + .iter() + .position(|&x| x == b'\'') + .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?; + let s = from_utf8(&self.bytes[0..pos]).map_err(|e| self.error(e.into()))?; + let mut chars = s.chars(); + + let first = chars + .next() + .ok_or_else(|| self.error(ErrorCode::ExpectedChar))?; + if chars.next().is_some() { + return self.err(ErrorCode::ExpectedChar); + } + + let _ = self.advance(pos); + + first + }; + + if !self.consume("'") { + return self.err(ErrorCode::ExpectedChar); + } + + Ok(c) + } + + pub fn comma(&mut self) -> Result<bool> { + self.skip_ws()?; + + if self.consume(",") { + self.skip_ws()?; + + Ok(true) + } else { + Ok(false) + } + } + + /// Only returns true if the char after `ident` cannot belong + /// to an identifier. + pub fn check_ident(&mut self, ident: &str) -> bool { + self.test_for(ident) && !self.check_ident_other_char(ident.len()) + } + + fn check_ident_other_char(&self, index: usize) -> bool { + self.bytes + .get(index) + .map_or(false, |&b| is_ident_other_char(b)) + } + + /// Should only be used on a working copy + pub fn check_tuple_struct(mut self) -> Result<bool> { + if self.identifier().is_err() { + // if there's no field ident, this is a tuple struct + return Ok(true); + } + + self.skip_ws()?; + + // if there is no colon after the ident, this can only be a unit struct + self.eat_byte().map(|c| c != b':') + } + + /// Only returns true if the char after `ident` cannot belong + /// to an identifier. + pub fn consume_ident(&mut self, ident: &str) -> bool { + if self.check_ident(ident) { + let _ = self.advance(ident.len()); + + true + } else { + false + } + } + + pub fn consume(&mut self, s: &str) -> bool { + if self.test_for(s) { + let _ = self.advance(s.len()); + + true + } else { + false + } + } + + fn consume_all(&mut self, all: &[&str]) -> Result<bool> { + all.iter() + .map(|elem| { + if self.consume(elem) { + self.skip_ws()?; + + Ok(true) + } else { + Ok(false) + } + }) + .fold(Ok(true), |acc, x| acc.and_then(|val| x.map(|x| x && val))) + } + + pub fn eat_byte(&mut self) -> Result<u8> { + let peek = self.peek_or_eof()?; + let _ = self.advance_single(); + + Ok(peek) + } + + pub fn err<T>(&self, kind: ErrorCode) -> Result<T> { + Err(self.error(kind)) + } + + pub fn error(&self, kind: ErrorCode) -> Error { + Error { + code: kind, + position: Position { + line: self.line, + col: self.column, + }, + } + } + + pub fn expect_byte(&mut self, byte: u8, error: ErrorCode) -> Result<()> { + self.eat_byte() + .and_then(|b| if b == byte { Ok(()) } else { self.err(error) }) + } + + /// Returns the extensions bit mask. + fn extensions(&mut self) -> Result<Extensions> { + if self.peek() != Some(b'#') { + return Ok(Extensions::empty()); + } + + if !self.consume_all(&["#", "!", "[", "enable", "("])? { + return self.err(ErrorCode::ExpectedAttribute); + } + + self.skip_ws()?; + let mut extensions = Extensions::empty(); + + loop { + let ident = self.identifier()?; + let extension = Extensions::from_ident(ident).ok_or_else(|| { + self.error(ErrorCode::NoSuchExtension( + from_utf8(ident).unwrap().to_owned(), + )) + })?; + + extensions |= extension; + + let comma = self.comma()?; + + // If we have no comma but another item, return an error + if !comma && self.check_ident_other_char(0) { + return self.err(ErrorCode::ExpectedComma); + } + + // If there's no comma, assume the list ended. + // If there is, it might be a trailing one, thus we only + // continue the loop if we get an ident char. + if !comma || !self.check_ident_other_char(0) { + break; + } + } + + self.skip_ws()?; + + if self.consume_all(&[")", "]"])? { + Ok(extensions) + } else { + Err(self.error(ErrorCode::ExpectedAttributeEnd)) + } + } + + pub fn float<T>(&mut self) -> Result<T> + where + T: FromStr, + { + for literal in &["inf", "-inf", "NaN"] { + if self.consume_ident(literal) { + return FromStr::from_str(literal).map_err(|_| unreachable!()); // must not fail + } + } + + let num_bytes = self.next_bytes_contained_in(is_float_char); + + let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) }; + let res = FromStr::from_str(s).map_err(|_| self.error(ErrorCode::ExpectedFloat)); + + let _ = self.advance(num_bytes); + + res + } + + pub fn identifier(&mut self) -> Result<&'a [u8]> { + let bytes = self.identifier_len()?; + let ident = &self.bytes[..bytes]; + let _ = self.advance(bytes); + + Ok(ident) + } + + pub fn identifier_len(&self) -> Result<usize> { + let next = self.peek_or_eof()?; + if is_ident_first_char(next) { + // If the next two bytes signify the start of a raw string literal, + // return an error. + if next == b'r' { + let second = self + .bytes + .get(1) + .ok_or_else(|| self.error(ErrorCode::Eof))?; + if *second == b'"' || *second == b'#' { + return self.err(ErrorCode::ExpectedIdentifier); + } + } + + let bytes = self.next_bytes_contained_in(is_ident_other_char); + + Ok(bytes) + } else { + self.err(ErrorCode::ExpectedIdentifier) + } + } + + pub fn next_bytes_contained_in(&self, allowed: fn(u8) -> bool) -> usize { + self.bytes.iter().take_while(|&&b| allowed(b)).count() + } + + pub fn next_bytes_is_float(&self) -> bool { + if let Some(byte) = self.peek() { + let skip = match byte { + b'+' | b'-' => 1, + _ => 0, + }; + let flen = self + .bytes + .iter() + .skip(skip) + .take_while(|&&b| is_float_char(b)) + .count(); + let ilen = self + .bytes + .iter() + .skip(skip) + .take_while(|&&b| is_int_char(b)) + .count(); + flen > ilen + } else { + false + } + } + + pub fn skip_ws(&mut self) -> Result<()> { + while self.peek().map_or(false, |c| is_whitespace_char(c)) { + let _ = self.advance_single(); + } + + if self.skip_comment()? { + self.skip_ws()?; + } + + Ok(()) + } + + pub fn peek(&self) -> Option<u8> { + self.bytes.get(0).cloned() + } + + pub fn peek_or_eof(&self) -> Result<u8> { + self.bytes + .get(0) + .cloned() + .ok_or_else(|| self.error(ErrorCode::Eof)) + } + + pub fn signed_integer<T>(&mut self) -> Result<T> + where + T: Num, + { + match self.peek_or_eof()? { + b'+' => { + let _ = self.advance_single(); + + self.any_integer(1) + } + b'-' => { + let _ = self.advance_single(); + + self.any_integer(-1) + } + _ => self.any_integer(1), + } + } + + pub fn string(&mut self) -> Result<ParsedStr<'a>> { + if self.consume("\"") { + self.escaped_string() + } else if self.consume("r") { + self.raw_string() + } else { + self.err(ErrorCode::ExpectedString) + } + } + + fn escaped_string(&mut self) -> Result<ParsedStr<'a>> { + use std::iter::repeat; + + let (i, end_or_escape) = self + .bytes + .iter() + .enumerate() + .find(|&(_, &b)| b == b'\\' || b == b'"') + .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?; + + if *end_or_escape == b'"' { + let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?; + + // Advance by the number of bytes of the string + // + 1 for the `"`. + let _ = self.advance(i + 1); + + Ok(ParsedStr::Slice(s)) + } else { + let mut i = i; + let mut s: Vec<_> = self.bytes[..i].to_vec(); + + loop { + let _ = self.advance(i + 1); + let character = self.parse_escape()?; + match character.len_utf8() { + 1 => s.push(character as u8), + len => { + let start = s.len(); + s.extend(repeat(0).take(len)); + character.encode_utf8(&mut s[start..]); + } + } + + let (new_i, end_or_escape) = self + .bytes + .iter() + .enumerate() + .find(|&(_, &b)| b == b'\\' || b == b'"') + .ok_or(ErrorCode::Eof) + .map_err(|e| self.error(e))?; + + i = new_i; + s.extend_from_slice(&self.bytes[..i]); + + if *end_or_escape == b'"' { + let _ = self.advance(i + 1); + + let s = String::from_utf8(s).map_err(|e| self.error(e.into()))?; + break Ok(ParsedStr::Allocated(s)); + } + } + } + } + + fn raw_string(&mut self) -> Result<ParsedStr<'a>> { + let num_hashes = self.bytes.iter().take_while(|&&b| b == b'#').count(); + let hashes = &self.bytes[..num_hashes]; + let _ = self.advance(num_hashes); + + if !self.consume("\"") { + return self.err(ErrorCode::ExpectedString); + } + + let ending = [&[b'"'], hashes].concat(); + let i = self + .bytes + .windows(num_hashes + 1) + .position(|window| window == ending.as_slice()) + .ok_or_else(|| self.error(ErrorCode::ExpectedStringEnd))?; + + let s = from_utf8(&self.bytes[..i]).map_err(|e| self.error(e.into()))?; + + // Advance by the number of bytes of the string + // + `num_hashes` + 1 for the `"`. + let _ = self.advance(i + num_hashes + 1); + + Ok(ParsedStr::Slice(s)) + } + + fn test_for(&self, s: &str) -> bool { + s.bytes() + .enumerate() + .all(|(i, b)| self.bytes.get(i).map_or(false, |t| *t == b)) + } + + pub fn unsigned_integer<T: Num>(&mut self) -> Result<T> { + self.any_integer(1) + } + + fn decode_ascii_escape(&mut self) -> Result<u8> { + let mut n = 0; + for _ in 0..2 { + n <<= 4; + let byte = self.eat_byte()?; + let decoded = self.decode_hex(byte)?; + n |= decoded; + } + + Ok(n) + } + + #[inline] + fn decode_hex(&self, c: u8) -> Result<u8> { + match c { + c @ b'0'..=b'9' => Ok(c - b'0'), + c @ b'a'..=b'f' => Ok(10 + c - b'a'), + c @ b'A'..=b'F' => Ok(10 + c - b'A'), + _ => self.err(ErrorCode::InvalidEscape("Non-hex digit found")), + } + } + + fn parse_escape(&mut self) -> Result<char> { + let c = match self.eat_byte()? { + b'\'' => '\'', + b'"' => '"', + b'\\' => '\\', + b'n' => '\n', + b'r' => '\r', + b't' => '\t', + b'x' => self.decode_ascii_escape()? as char, + b'u' => { + self.expect_byte(b'{', ErrorCode::InvalidEscape("Missing {"))?; + + let mut bytes: u32 = 0; + let mut num_digits = 0; + + while num_digits < 6 { + let byte = self.peek_or_eof()?; + + if byte == b'}' { + break; + } else { + self.advance_single()?; + } + + let byte = self.decode_hex(byte)?; + bytes <<= 4; + bytes |= byte as u32; + + num_digits += 1; + } + + if num_digits == 0 { + return self.err(ErrorCode::InvalidEscape( + "Expected 1-6 digits, got 0 digits", + )); + } + + self.expect_byte(b'}', ErrorCode::InvalidEscape("No } at the end"))?; + char_from_u32(bytes) + .ok_or_else(|| self.error(ErrorCode::InvalidEscape("Not a valid char")))? + } + _ => { + return self.err(ErrorCode::InvalidEscape("Unknown escape character")); + } + }; + + Ok(c) + } + + fn skip_comment(&mut self) -> Result<bool> { + if self.consume("/") { + match self.eat_byte()? { + b'/' => { + let bytes = self.bytes.iter().take_while(|&&b| b != b'\n').count(); + + let _ = self.advance(bytes); + } + b'*' => { + let mut level = 1; + + while level > 0 { + let bytes = self + .bytes + .iter() + .take_while(|&&b| b != b'/' && b != b'*') + .count(); + + if self.bytes.is_empty() { + return self.err(ErrorCode::UnclosedBlockComment); + } + + let _ = self.advance(bytes); + + // check whether / or * and take action + if self.consume("/*") { + level += 1; + } else if self.consume("*/") { + level -= 1; + } else { + self.eat_byte() + .map_err(|_| self.error(ErrorCode::UnclosedBlockComment))?; + } + } + } + b => return self.err(ErrorCode::UnexpectedByte(b as char)), + } + + Ok(true) + } else { + Ok(false) + } + } +} + +pub trait Num { + fn from_u8(x: u8) -> Self; + + /// Returns `true` on overflow + fn checked_mul_ext(&mut self, x: u8) -> bool; + + /// Returns `true` on overflow + fn checked_add_ext(&mut self, x: u8) -> bool; + + /// Returns `true` on overflow + fn checked_sub_ext(&mut self, x: u8) -> bool; +} + +macro_rules! impl_num { + ($ty:ident) => { + impl Num for $ty { + fn from_u8(x: u8) -> Self { + x as $ty + } + + fn checked_mul_ext(&mut self, x: u8) -> bool { + match self.checked_mul(Self::from_u8(x)) { + Some(n) => { + *self = n; + false + } + None => true, + } + } + + fn checked_add_ext(&mut self, x: u8) -> bool { + match self.checked_add(Self::from_u8(x)) { + Some(n) => { + *self = n; + false + } + None => true, + } + } + + fn checked_sub_ext(&mut self, x: u8) -> bool { + match self.checked_sub(Self::from_u8(x)) { + Some(n) => { + *self = n; + false + } + None => true, + } + } + } + }; + ($($tys:ident)*) => { + $( impl_num!($tys); )* + }; +} + +impl_num!(u8 u16 u32 u64 u128 i8 i16 i32 i64 i128); + +#[derive(Clone, Debug)] +pub enum ParsedStr<'a> { + Allocated(String), + Slice(&'a str), +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Position { + pub line: usize, + pub col: usize, +} + +impl Display for Position { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{}:{}", self.line, self.col) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn decode_x10() { + let mut bytes = Bytes::new(b"10").unwrap(); + assert_eq!(bytes.decode_ascii_escape(), Ok(0x10)); + } +} diff --git a/third_party/rust/ron/src/ser/mod.rs b/third_party/rust/ron/src/ser/mod.rs new file mode 100644 index 0000000000..ca1cea3dad --- /dev/null +++ b/third_party/rust/ron/src/ser/mod.rs @@ -0,0 +1,1089 @@ +use serde::{ser, Deserialize, Serialize}; +use std::io; + +use crate::error::{Error, Result}; +use crate::extensions::Extensions; + +mod value; + +/// Serializes `value` into `writer` +pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: Serialize, +{ + let mut s = Serializer::new(writer, None, false)?; + value.serialize(&mut s) +} + +/// Serializes `value` into `writer` in a pretty way. +pub fn to_writer_pretty<W, T>(writer: W, value: &T, config: PrettyConfig) -> Result<()> +where + W: io::Write, + T: Serialize, +{ + let mut s = Serializer::new(writer, Some(config), false)?; + value.serialize(&mut s) +} + +/// Serializes `value` and returns it as string. +/// +/// This function does not generate any newlines or nice formatting; +/// if you want that, you can use `to_string_pretty` instead. +pub fn to_string<T>(value: &T) -> Result<String> +where + T: Serialize, +{ + let buf = Vec::new(); + let mut s = Serializer::new(buf, None, false)?; + value.serialize(&mut s)?; + Ok(String::from_utf8(s.output).expect("Ron should be utf-8")) +} + +/// Serializes `value` in the recommended RON layout in a pretty way. +pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String> +where + T: Serialize, +{ + let buf = Vec::new(); + let mut s = Serializer::new(buf, Some(config), false)?; + value.serialize(&mut s)?; + Ok(String::from_utf8(s.output).expect("Ron should be utf-8")) +} + +/// Pretty serializer state +struct Pretty { + indent: usize, + sequence_index: Vec<usize>, +} + +/// Pretty serializer configuration. +/// +/// # Examples +/// +/// ``` +/// use ron::ser::PrettyConfig; +/// +/// let my_config = PrettyConfig::new() +/// .with_depth_limit(4) +/// // definitely superior (okay, just joking) +/// .with_indentor("\t".to_owned()); +/// ``` +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct PrettyConfig { + /// Limit the pretty-ness up to the given depth. + #[serde(default = "default_depth_limit")] + pub depth_limit: usize, + /// New line string + #[serde(default = "default_new_line")] + pub new_line: String, + /// Indentation string + #[serde(default = "default_indentor")] + pub indentor: String, + /// Separate tuple members with indentation + #[serde(default = "default_separate_tuple_members")] + pub separate_tuple_members: bool, + /// Enumerate array items in comments + #[serde(default = "default_enumerate_arrays")] + pub enumerate_arrays: bool, + /// Always include the decimal in floats + #[serde(default = "default_decimal_floats")] + pub decimal_floats: bool, + /// Enable extensions. Only configures 'implicit_some' for now. + pub extensions: Extensions, + /// Private field to ensure adding a field is non-breaking. + #[serde(skip)] + _future_proof: (), +} + +impl PrettyConfig { + /// Creates a default `PrettyConfig`. + pub fn new() -> Self { + Default::default() + } + + /// Limits the pretty-formatting based on the number of indentations. + /// I.e., with a depth limit of 5, starting with an element of depth + /// (indentation level) 6, everything will be put into the same line, + /// without pretty formatting. + /// + /// Default: [std::usize::MAX] + pub fn with_depth_limit(mut self, depth_limit: usize) -> Self { + self.depth_limit = depth_limit; + + self + } + + /// Configures the newlines used for serialization. + /// + /// Default: `\r\n` on Windows, `\n` otherwise + pub fn with_new_line(mut self, new_line: String) -> Self { + self.new_line = new_line; + + self + } + + /// Configures the string sequence used for indentation. + /// + /// Default: 4 spaces + pub fn with_indentor(mut self, indentor: String) -> Self { + self.indentor = indentor; + + self + } + + /// Configures whether tuples are single- or multi-line. + /// If set to `true`, tuples will have their fields indented and in new + /// lines. If set to `false`, tuples will be serialized without any + /// newlines or indentations. + /// + /// Default: `false` + pub fn with_separate_tuple_members(mut self, separate_tuple_members: bool) -> Self { + self.separate_tuple_members = separate_tuple_members; + + self + } + + /// Configures whether a comment shall be added to every array element, + /// indicating the index. + /// + /// Default: `false` + pub fn with_enumerate_arrays(mut self, enumerate_arrays: bool) -> Self { + self.enumerate_arrays = enumerate_arrays; + + self + } + + /// Configures whether floats should always include a decimal. + /// When false `1.0` will serialize as `1` + /// When true `1.0` will serialize as `1.0` + /// + /// Default: `false` + pub fn with_decimal_floats(mut self, decimal_floats: bool) -> Self { + self.decimal_floats = decimal_floats; + + self + } + + /// Configures extensions + /// + /// Default: Extensions::empty() + pub fn with_extensions(mut self, extensions: Extensions) -> Self { + self.extensions = extensions; + + self + } +} + +fn default_depth_limit() -> usize { + !0 +} + +fn default_new_line() -> String { + #[cfg(not(target_os = "windows"))] + let new_line = "\n".to_string(); + #[cfg(target_os = "windows")] + let new_line = "\r\n".to_string(); + + new_line +} + +fn default_decimal_floats() -> bool { + false +} + +fn default_indentor() -> String { + " ".to_string() +} + +fn default_separate_tuple_members() -> bool { + false +} + +fn default_enumerate_arrays() -> bool { + false +} + +impl Default for PrettyConfig { + fn default() -> Self { + PrettyConfig { + depth_limit: default_depth_limit(), + new_line: default_new_line(), + indentor: default_indentor(), + separate_tuple_members: default_separate_tuple_members(), + enumerate_arrays: default_enumerate_arrays(), + extensions: Extensions::default(), + decimal_floats: default_decimal_floats(), + _future_proof: (), + } + } +} + +/// The RON serializer. +/// +/// You can just use `to_string` for deserializing a value. +/// If you want it pretty-printed, take a look at the `pretty` module. +pub struct Serializer<W: io::Write> { + output: W, + pretty: Option<(PrettyConfig, Pretty)>, + struct_names: bool, + is_empty: Option<bool>, +} + +impl<W: io::Write> Serializer<W> { + /// Creates a new `Serializer`. + /// + /// Most of the time you can just use `to_string` or `to_string_pretty`. + pub fn new(mut writer: W, config: Option<PrettyConfig>, struct_names: bool) -> Result<Self> { + if let Some(conf) = &config { + if conf.extensions.contains(Extensions::IMPLICIT_SOME) { + writer.write_all(b"#![enable(implicit_some)]")?; + writer.write_all(conf.new_line.as_bytes())?; + }; + }; + Ok(Serializer { + output: writer, + pretty: config.map(|conf| { + ( + conf, + Pretty { + indent: 0, + sequence_index: Vec::new(), + }, + ) + }), + struct_names, + is_empty: None, + }) + } + + fn is_pretty(&self) -> bool { + match self.pretty { + Some((ref config, ref pretty)) => pretty.indent <= config.depth_limit, + None => false, + } + } + + fn separate_tuple_members(&self) -> bool { + self.pretty + .as_ref() + .map_or(false, |&(ref config, _)| config.separate_tuple_members) + } + + fn decimal_floats(&self) -> bool { + self.pretty + .as_ref() + .map_or(false, |&(ref config, _)| config.decimal_floats) + } + + fn extensions(&self) -> Extensions { + self.pretty + .as_ref() + .map_or(Extensions::empty(), |&(ref config, _)| config.extensions) + } + + fn start_indent(&mut self) -> Result<()> { + if let Some((ref config, ref mut pretty)) = self.pretty { + pretty.indent += 1; + if pretty.indent <= config.depth_limit { + let is_empty = self.is_empty.unwrap_or(false); + + if !is_empty { + self.output.write_all(config.new_line.as_bytes())?; + } + } + } + Ok(()) + } + + fn indent(&mut self) -> io::Result<()> { + if let Some((ref config, ref pretty)) = self.pretty { + if pretty.indent <= config.depth_limit { + for _ in 0..pretty.indent { + self.output.write_all(config.indentor.as_bytes())?; + } + } + } + Ok(()) + } + + fn end_indent(&mut self) -> io::Result<()> { + if let Some((ref config, ref mut pretty)) = self.pretty { + if pretty.indent <= config.depth_limit { + let is_empty = self.is_empty.unwrap_or(false); + + if !is_empty { + for _ in 1..pretty.indent { + self.output.write_all(config.indentor.as_bytes())?; + } + } + } + pretty.indent -= 1; + + self.is_empty = None; + } + Ok(()) + } + + fn serialize_escaped_str(&mut self, value: &str) -> io::Result<()> { + self.output.write_all(b"\"")?; + let mut scalar = [0u8; 4]; + for c in value.chars().flat_map(|c| c.escape_debug()) { + self.output + .write_all(c.encode_utf8(&mut scalar).as_bytes())?; + } + self.output.write_all(b"\"")?; + Ok(()) + } +} + +impl<'a, W: io::Write> ser::Serializer for &'a mut Serializer<W> { + type Error = Error; + type Ok = (); + type SerializeMap = Compound<'a, W>; + type SerializeSeq = Compound<'a, W>; + type SerializeStruct = Compound<'a, W>; + type SerializeStructVariant = Compound<'a, W>; + type SerializeTuple = Compound<'a, W>; + type SerializeTupleStruct = Compound<'a, W>; + type SerializeTupleVariant = Compound<'a, W>; + + fn serialize_bool(self, v: bool) -> Result<()> { + self.output.write_all(if v { b"true" } else { b"false" })?; + Ok(()) + } + + fn serialize_i8(self, v: i8) -> Result<()> { + self.serialize_i128(v as i128) + } + + fn serialize_i16(self, v: i16) -> Result<()> { + self.serialize_i128(v as i128) + } + + fn serialize_i32(self, v: i32) -> Result<()> { + self.serialize_i128(v as i128) + } + + fn serialize_i64(self, v: i64) -> Result<()> { + self.serialize_i128(v as i128) + } + + fn serialize_i128(self, v: i128) -> Result<()> { + // TODO optimize + write!(self.output, "{}", v)?; + Ok(()) + } + + fn serialize_u8(self, v: u8) -> Result<()> { + self.serialize_u128(v as u128) + } + + fn serialize_u16(self, v: u16) -> Result<()> { + self.serialize_u128(v as u128) + } + + fn serialize_u32(self, v: u32) -> Result<()> { + self.serialize_u128(v as u128) + } + + fn serialize_u64(self, v: u64) -> Result<()> { + self.serialize_u128(v as u128) + } + + fn serialize_u128(self, v: u128) -> Result<()> { + write!(self.output, "{}", v)?; + Ok(()) + } + + fn serialize_f32(self, v: f32) -> Result<()> { + write!(self.output, "{}", v)?; + // TODO: use f32::EPSILON when minimum supported rust version is 1.43 + pub const EPSILON: f32 = 1.19209290e-07_f32; + if self.decimal_floats() && (v - v.floor()).abs() < EPSILON { + write!(self.output, ".0")?; + } + Ok(()) + } + + fn serialize_f64(self, v: f64) -> Result<()> { + write!(self.output, "{}", v)?; + // TODO: use f64::EPSILON when minimum supported rust version is 1.43 + pub const EPSILON: f64 = 2.2204460492503131e-16_f64; + if self.decimal_floats() && (v - v.floor()).abs() < EPSILON { + write!(self.output, ".0")?; + } + Ok(()) + } + + fn serialize_char(self, v: char) -> Result<()> { + self.output.write_all(b"'")?; + if v == '\\' || v == '\'' { + self.output.write_all(b"\\")?; + } + write!(self.output, "{}", v)?; + self.output.write_all(b"'")?; + Ok(()) + } + + fn serialize_str(self, v: &str) -> Result<()> { + self.serialize_escaped_str(v)?; + + Ok(()) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + self.serialize_str(base64::encode(v).as_str()) + } + + fn serialize_none(self) -> Result<()> { + self.output.write_all(b"None")?; + + Ok(()) + } + + fn serialize_some<T>(self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let implicit_some = self.extensions().contains(Extensions::IMPLICIT_SOME); + if !implicit_some { + self.output.write_all(b"Some(")?; + } + value.serialize(&mut *self)?; + if !implicit_some { + self.output.write_all(b")")?; + } + + Ok(()) + } + + fn serialize_unit(self) -> Result<()> { + self.output.write_all(b"()")?; + + Ok(()) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result<()> { + if self.struct_names { + self.output.write_all(name.as_bytes())?; + + Ok(()) + } else { + self.serialize_unit() + } + } + + fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> { + self.output.write_all(variant.as_bytes())?; + + Ok(()) + } + + fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + if self.struct_names { + self.output.write_all(name.as_bytes())?; + } + + self.output.write_all(b"(")?; + value.serialize(&mut *self)?; + self.output.write_all(b")")?; + Ok(()) + } + + fn serialize_newtype_variant<T>( + self, + _: &'static str, + _: u32, + variant: &'static str, + value: &T, + ) -> Result<()> + where + T: ?Sized + Serialize, + { + self.output.write_all(variant.as_bytes())?; + self.output.write_all(b"(")?; + + value.serialize(&mut *self)?; + + self.output.write_all(b")")?; + Ok(()) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> { + self.output.write_all(b"[")?; + + if let Some(len) = len { + self.is_empty = Some(len == 0); + } + + self.start_indent()?; + + if let Some((_, ref mut pretty)) = self.pretty { + pretty.sequence_index.push(0); + } + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> { + self.output.write_all(b"(")?; + + if self.separate_tuple_members() { + self.is_empty = Some(len == 0); + + self.start_indent()?; + } + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct> { + if self.struct_names { + self.output.write_all(name.as_bytes())?; + } + + self.serialize_tuple(len) + } + + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant> { + self.output.write_all(variant.as_bytes())?; + self.output.write_all(b"(")?; + + if self.separate_tuple_members() { + self.is_empty = Some(len == 0); + + self.start_indent()?; + } + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> { + self.output.write_all(b"{")?; + + if let Some(len) = len { + self.is_empty = Some(len == 0); + } + + self.start_indent()?; + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> { + if self.struct_names { + self.output.write_all(name.as_bytes())?; + } + self.output.write_all(b"(")?; + + self.is_empty = Some(len == 0); + self.start_indent()?; + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant> { + self.output.write_all(variant.as_bytes())?; + self.output.write_all(b"(")?; + + self.is_empty = Some(len == 0); + self.start_indent()?; + + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } +} + +impl<'a, W: io::Write> ser::SerializeSeq for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_element<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let ser = match self { + Compound::Map { + state: ref mut s @ State::First, + ser, + } => { + *s = State::Rest; + ser + } + Compound::Map { + state: State::Rest, + ser, + } => { + ser.output.write_all(b",")?; + if let Some((ref config, ref mut pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + if config.enumerate_arrays { + assert!(config.new_line.contains('\n')); + let index = pretty.sequence_index.last_mut().unwrap(); + //TODO: when /**/ comments are supported, prepend the index + // to an element instead of appending it. + write!(ser.output, "// [{}]", index).unwrap(); + *index += 1; + } + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + }; + ser.indent()?; + + value.serialize(&mut **ser)?; + + Ok(()) + } + + fn end(self) -> Result<()> { + let ser = match self { + Compound::Map { + ser, + state: State::Rest, + } => { + if let Some((ref config, ref mut pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(b",")?; + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + Compound::Map { ser, .. } => ser, + }; + ser.end_indent()?; + + if let Some((_, ref mut pretty)) = ser.pretty { + pretty.sequence_index.pop(); + } + + ser.output.write_all(b"]")?; + Ok(()) + } +} +pub enum State { + First, + Rest, +} +pub enum Compound<'a, W: io::Write> { + Map { + ser: &'a mut Serializer<W>, + state: State, + }, +} +impl<'a, W: io::Write> ser::SerializeTuple for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_element<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let ser = match self { + Compound::Map { + ser, + state: ref mut s @ State::First, + } => { + *s = State::Rest; + ser + } + Compound::Map { ser, .. } => { + ser.output.write_all(b",")?; + if let Some((ref config, ref pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(if ser.separate_tuple_members() { + config.new_line.as_bytes() + } else { + b" " + })?; + } + } + ser + } + }; + + if ser.separate_tuple_members() { + ser.indent()?; + } + + value.serialize(&mut **ser)?; + + Ok(()) + } + + fn end(self) -> Result<()> { + let ser = match self { + Compound::Map { + ser, + state: State::Rest, + } => { + if let Some((ref config, ref pretty)) = ser.pretty { + if ser.separate_tuple_members() && pretty.indent <= config.depth_limit { + ser.output.write_all(b",")?; + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + Compound::Map { ser, .. } => ser, + }; + if ser.separate_tuple_members() { + ser.end_indent()?; + } + + ser.output.write_all(b")")?; + + Ok(()) + } +} + +// Same thing but for tuple structs. +impl<'a, W: io::Write> ser::SerializeTupleStruct for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_field<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeTuple::serialize_element(self, value) + } + + fn end(self) -> Result<()> { + ser::SerializeTuple::end(self) + } +} + +impl<'a, W: io::Write> ser::SerializeTupleVariant for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_field<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeTuple::serialize_element(self, value) + } + + fn end(self) -> Result<()> { + ser::SerializeTuple::end(self) + } +} + +impl<'a, W: io::Write> ser::SerializeMap for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_key<T>(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let ser = match self { + Compound::Map { + ser, + state: ref mut s @ State::First, + } => { + *s = State::Rest; + ser + } + Compound::Map { + ser, + state: State::Rest, + } => { + ser.output.write_all(b",")?; + + if let Some((ref config, ref pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + }; + ser.indent()?; + key.serialize(&mut **ser) + } + + fn serialize_value<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + Compound::Map { ser, .. } => { + ser.output.write_all(b":")?; + + if ser.is_pretty() { + ser.output.write_all(b" ")?; + } + + value.serialize(&mut **ser)?; + } + } + + Ok(()) + } + + fn end(self) -> Result<()> { + let ser = match self { + Compound::Map { + ser, + state: State::Rest, + } => { + if let Some((ref config, ref pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(b",")?; + ser.output.write_all(config.new_line.as_bytes())?; + } + } + + ser + } + Compound::Map { ser, .. } => ser, + }; + ser.end_indent()?; + ser.output.write_all(b"}")?; + Ok(()) + } +} + +impl<'a, W: io::Write> ser::SerializeStruct for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let ser = match self { + Compound::Map { + ser, + state: ref mut s @ State::First, + } => { + *s = State::Rest; + ser + } + Compound::Map { ser, .. } => { + ser.output.write_all(b",")?; + + if let Some((ref config, ref pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + }; + ser.indent()?; + ser.output.write_all(key.as_bytes())?; + ser.output.write_all(b":")?; + + if ser.is_pretty() { + ser.output.write_all(b" ")?; + } + + value.serialize(&mut **ser)?; + + Ok(()) + } + + fn end(self) -> Result<()> { + let ser = match self { + Compound::Map { + ser, + state: State::Rest, + } => { + if let Some((ref config, ref pretty)) = ser.pretty { + if pretty.indent <= config.depth_limit { + ser.output.write_all(b",")?; + ser.output.write_all(config.new_line.as_bytes())?; + } + } + ser + } + Compound::Map { ser, .. } => ser, + }; + ser.end_indent()?; + ser.output.write_all(b")")?; + Ok(()) + } +} + +impl<'a, W: io::Write> ser::SerializeStructVariant for Compound<'a, W> { + type Error = Error; + type Ok = (); + + fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeStruct::serialize_field(self, key, value) + } + + fn end(self) -> Result<()> { + ser::SerializeStruct::end(self) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Serialize)] + struct EmptyStruct1; + + #[derive(Serialize)] + struct EmptyStruct2 {} + + #[derive(Serialize)] + struct MyStruct { + x: f32, + y: f32, + } + + #[derive(Serialize)] + enum MyEnum { + A, + B(bool), + C(bool, f32), + D { a: i32, b: i32 }, + } + + #[test] + fn test_empty_struct() { + assert_eq!(to_string(&EmptyStruct1).unwrap(), "()"); + assert_eq!(to_string(&EmptyStruct2 {}).unwrap(), "()"); + } + + #[test] + fn test_struct() { + let my_struct = MyStruct { x: 4.0, y: 7.0 }; + + assert_eq!(to_string(&my_struct).unwrap(), "(x:4,y:7)"); + + #[derive(Serialize)] + struct NewType(i32); + + assert_eq!(to_string(&NewType(42)).unwrap(), "(42)"); + + #[derive(Serialize)] + struct TupleStruct(f32, f32); + + assert_eq!(to_string(&TupleStruct(2.0, 5.0)).unwrap(), "(2,5)"); + } + + #[test] + fn test_option() { + assert_eq!(to_string(&Some(1u8)).unwrap(), "Some(1)"); + assert_eq!(to_string(&None::<u8>).unwrap(), "None"); + } + + #[test] + fn test_enum() { + assert_eq!(to_string(&MyEnum::A).unwrap(), "A"); + assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true)"); + assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5)"); + assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3)"); + } + + #[test] + fn test_array() { + let empty: [i32; 0] = []; + assert_eq!(to_string(&empty).unwrap(), "()"); + let empty_ref: &[i32] = ∅ + assert_eq!(to_string(&empty_ref).unwrap(), "[]"); + + assert_eq!(to_string(&[2, 3, 4i32]).unwrap(), "(2,3,4)"); + assert_eq!(to_string(&(&[2, 3, 4i32] as &[i32])).unwrap(), "[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); + + let s = to_string(&map).unwrap(); + s.starts_with("{"); + s.contains("(true,false):4"); + s.contains("(false,false):123"); + s.ends_with("}"); + } + + #[test] + fn test_string() { + assert_eq!(to_string(&"Some string").unwrap(), "\"Some string\""); + } + + #[test] + fn test_char() { + assert_eq!(to_string(&'c').unwrap(), "'c'"); + } + + #[test] + fn test_escape() { + assert_eq!(to_string(&r#""Quoted""#).unwrap(), r#""\"Quoted\"""#); + } + + #[test] + fn test_byte_stream() { + use serde_bytes; + + let small: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; + assert_eq!( + to_string(&small).unwrap(), + "(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)" + ); + + let large = vec![255u8; 64]; + let large = serde_bytes::Bytes::new(&large); + assert_eq!( + to_string(&large).unwrap(), + concat!( + "\"/////////////////////////////////////////", + "////////////////////////////////////////////w==\"" + ) + ); + } +} diff --git a/third_party/rust/ron/src/ser/value.rs b/third_party/rust/ron/src/ser/value.rs new file mode 100644 index 0000000000..1a47758986 --- /dev/null +++ b/third_party/rust/ron/src/ser/value.rs @@ -0,0 +1,23 @@ +use serde::ser::{Serialize, Serializer}; + +use crate::value::{Number, Value}; + +impl Serialize for Value { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + match *self { + Value::Bool(b) => serializer.serialize_bool(b), + Value::Char(c) => serializer.serialize_char(c), + Value::Map(ref m) => Serialize::serialize(m, serializer), + Value::Number(Number::Float(ref f)) => serializer.serialize_f64(f.get()), + Value::Number(Number::Integer(i)) => serializer.serialize_i64(i), + Value::Option(Some(ref o)) => serializer.serialize_some(o.as_ref()), + Value::Option(None) => serializer.serialize_none(), + Value::String(ref s) => serializer.serialize_str(s), + Value::Seq(ref s) => Serialize::serialize(s, serializer), + Value::Unit => serializer.serialize_unit(), + } + } +} diff --git a/third_party/rust/ron/src/value.rs b/third_party/rust/ron/src/value.rs new file mode 100644 index 0000000000..e5387df022 --- /dev/null +++ b/third_party/rust/ron/src/value.rs @@ -0,0 +1,553 @@ +//! Value module. + +use serde::{ + de::{ + DeserializeOwned, DeserializeSeed, Deserializer, Error as SerdeError, MapAccess, SeqAccess, + Visitor, + }, + forward_to_deserialize_any, Deserialize, Serialize, +}; +use std::{ + cmp::{Eq, Ordering}, + hash::{Hash, Hasher}, + iter::FromIterator, + ops::{Index, IndexMut}, +}; + +use crate::de::{Error as RonError, Result}; + +/// A `Value` to `Value` map. +/// +/// This structure either uses a [BTreeMap](std::collections::BTreeMap) or the +/// [IndexMap](indexmap::IndexMap) internally. +/// The latter can be used by enabling the `indexmap` feature. This can be used +/// to preserve the order of the parsed map. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub struct Map(MapInner); + +impl Map { + /// Creates a new, empty `Map`. + pub fn new() -> Map { + Default::default() + } + + /// Returns the number of elements in the map. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Returns `true` if `self.len() == 0`, `false` otherwise. + pub fn is_empty(&self) -> usize { + self.0.len() + } + + /// Inserts a new element, returning the previous element with this `key` if + /// there was any. + pub fn insert(&mut self, key: Value, value: Value) -> Option<Value> { + self.0.insert(key, value) + } + + /// Removes an element by its `key`. + pub fn remove(&mut self, key: &Value) -> Option<Value> { + self.0.remove(key) + } + + /// Iterate all key-value pairs. + pub fn iter(&self) -> impl Iterator<Item = (&Value, &Value)> + DoubleEndedIterator { + self.0.iter() + } + + /// Iterate all key-value pairs mutably. + pub fn iter_mut(&mut self) -> impl Iterator<Item = (&Value, &mut Value)> + DoubleEndedIterator { + self.0.iter_mut() + } + + /// Iterate all keys. + pub fn keys(&self) -> impl Iterator<Item = &Value> + DoubleEndedIterator { + self.0.keys() + } + + /// Iterate all values. + pub fn values(&self) -> impl Iterator<Item = &Value> + DoubleEndedIterator { + self.0.values() + } + + /// Iterate all values mutably. + pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Value> + DoubleEndedIterator { + self.0.values_mut() + } +} + +impl FromIterator<(Value, Value)> for Map { + fn from_iter<T: IntoIterator<Item = (Value, Value)>>(iter: T) -> Self { + Map(MapInner::from_iter(iter)) + } +} + +/// Note: equality is only given if both values and order of values match +impl Eq for Map {} + +impl Hash for Map { + fn hash<H: Hasher>(&self, state: &mut H) { + self.iter().for_each(|x| x.hash(state)); + } +} + +impl Index<&Value> for Map { + type Output = Value; + + fn index(&self, index: &Value) -> &Self::Output { + &self.0[index] + } +} + +impl IndexMut<&Value> for Map { + fn index_mut(&mut self, index: &Value) -> &mut Self::Output { + self.0.get_mut(index).expect("no entry found for key") + } +} + +impl Ord for Map { + fn cmp(&self, other: &Map) -> Ordering { + self.iter().cmp(other.iter()) + } +} + +/// Note: equality is only given if both values and order of values match +impl PartialEq for Map { + fn eq(&self, other: &Map) -> bool { + self.iter().zip(other.iter()).all(|(a, b)| a == b) + } +} + +impl PartialOrd for Map { + fn partial_cmp(&self, other: &Map) -> Option<Ordering> { + self.iter().partial_cmp(other.iter()) + } +} + +#[cfg(not(feature = "indexmap"))] +type MapInner = std::collections::BTreeMap<Value, Value>; +#[cfg(feature = "indexmap")] +type MapInner = indexmap::IndexMap<Value, Value>; + +/// A wrapper for a number, which can be either `f64` or `i64`. +#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)] +pub enum Number { + Integer(i64), + Float(Float), +} + +/// A wrapper for `f64`, which guarantees that the inner value +/// is finite and thus implements `Eq`, `Hash` and `Ord`. +#[derive(Copy, Clone, Debug)] +pub struct Float(f64); + +impl Float { + /// Construct a new `Float`. + pub fn new(v: f64) -> Self { + Float(v) + } + + /// Returns the wrapped float. + pub fn get(self) -> f64 { + self.0 + } +} + +impl Number { + /// Construct a new number. + pub fn new(v: impl Into<Number>) -> Self { + v.into() + } + + /// Returns the `f64` representation of the number regardless of whether the number is stored + /// as a float or integer. + /// + /// # Example + /// + /// ``` + /// # use ron::value::Number; + /// let i = Number::new(5); + /// let f = Number::new(2.0); + /// assert_eq!(i.into_f64(), 5.0); + /// assert_eq!(f.into_f64(), 2.0); + /// ``` + pub fn into_f64(self) -> f64 { + self.map_to(|i| i as f64, |f| f) + } + + /// If the `Number` is a float, return it. Otherwise return `None`. + /// + /// # Example + /// + /// ``` + /// # use ron::value::Number; + /// let i = Number::new(5); + /// let f = Number::new(2.0); + /// assert_eq!(i.as_f64(), None); + /// assert_eq!(f.as_f64(), Some(2.0)); + /// ``` + pub fn as_f64(self) -> Option<f64> { + self.map_to(|_| None, Some) + } + + /// If the `Number` is an integer, return it. Otherwise return `None`. + /// + /// # Example + /// + /// ``` + /// # use ron::value::Number; + /// let i = Number::new(5); + /// let f = Number::new(2.0); + /// assert_eq!(i.as_i64(), Some(5)); + /// assert_eq!(f.as_i64(), None); + /// ``` + pub fn as_i64(self) -> Option<i64> { + self.map_to(Some, |_| None) + } + + /// Map this number to a single type using the appropriate closure. + /// + /// # Example + /// + /// ``` + /// # use ron::value::Number; + /// let i = Number::new(5); + /// let f = Number::new(2.0); + /// assert!(i.map_to(|i| i > 3, |f| f > 3.0)); + /// assert!(!f.map_to(|i| i > 3, |f| f > 3.0)); + /// ``` + pub fn map_to<T>( + self, + integer_fn: impl FnOnce(i64) -> T, + float_fn: impl FnOnce(f64) -> T, + ) -> T { + match self { + Number::Integer(i) => integer_fn(i), + Number::Float(Float(f)) => float_fn(f), + } + } +} + +impl From<f64> for Number { + fn from(f: f64) -> Number { + Number::Float(Float(f)) + } +} + +impl From<i64> for Number { + fn from(i: i64) -> Number { + Number::Integer(i) + } +} + +impl From<i32> for Number { + fn from(i: i32) -> Number { + Number::Integer(i as i64) + } +} + +// The following number conversion checks if the integer fits losslessly into an i64, before +// constructing a Number::Integer variant. If not, the conversion defaults to float. + +impl From<u64> for Number { + fn from(i: u64) -> Number { + if i as i64 as u64 == i { + Number::Integer(i as i64) + } else { + Number::new(i as f64) + } + } +} + +/// Partial equality comparison +/// In order to be able to use `Number` as a mapping key, NaN floating values +/// wrapped in `Float` are equals to each other. It is not the case for +/// underlying `f64` values itself. +impl PartialEq for Float { + fn eq(&self, other: &Self) -> bool { + self.0.is_nan() && other.0.is_nan() || self.0 == other.0 + } +} + +/// Equality comparison +/// In order to be able to use `Float` as a mapping key, NaN floating values +/// wrapped in `Float` are equals to each other. It is not the case for +/// underlying `f64` values itself. +impl Eq for Float {} + +impl Hash for Float { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u64(self.0 as u64); + } +} + +/// Partial ordering comparison +/// In order to be able to use `Number` as a mapping key, NaN floating values +/// wrapped in `Number` are equals to each other and are less then any other +/// floating value. It is not the case for the underlying `f64` values themselves. +/// ``` +/// use ron::value::Number; +/// assert!(Number::new(std::f64::NAN) < Number::new(std::f64::NEG_INFINITY)); +/// assert_eq!(Number::new(std::f64::NAN), Number::new(std::f64::NAN)); +/// ``` +impl PartialOrd for Float { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + match (self.0.is_nan(), other.0.is_nan()) { + (true, true) => Some(Ordering::Equal), + (true, false) => Some(Ordering::Less), + (false, true) => Some(Ordering::Greater), + _ => self.0.partial_cmp(&other.0), + } + } +} + +/// Ordering comparison +/// In order to be able to use `Float` as a mapping key, NaN floating values +/// wrapped in `Float` are equals to each other and are less then any other +/// floating value. It is not the case for underlying `f64` values itself. See +/// the `PartialEq` implementation. +impl Ord for Float { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).expect("Bug: Contract violation") + } +} + +#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Value { + Bool(bool), + Char(char), + Map(Map), + Number(Number), + Option(Option<Box<Value>>), + String(String), + Seq(Vec<Value>), + Unit, +} + +impl Value { + /// Tries to deserialize this `Value` into `T`. + pub fn into_rust<T>(self) -> Result<T> + where + T: DeserializeOwned, + { + T::deserialize(self) + } +} + +/// Deserializer implementation for RON `Value`. +/// This does not support enums (because `Value` doesn't store them). +impl<'de> Deserializer<'de> for Value { + type Error = RonError; + + forward_to_deserialize_any! { + bool f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + match self { + Value::Bool(b) => visitor.visit_bool(b), + Value::Char(c) => visitor.visit_char(c), + Value::Map(m) => visitor.visit_map(MapAccessor { + keys: m.keys().cloned().rev().collect(), + values: m.values().cloned().rev().collect(), + }), + Value::Number(Number::Float(ref f)) => visitor.visit_f64(f.get()), + Value::Number(Number::Integer(i)) => visitor.visit_i64(i), + Value::Option(Some(o)) => visitor.visit_some(*o), + Value::Option(None) => visitor.visit_none(), + Value::String(s) => visitor.visit_string(s), + Value::Seq(mut seq) => { + seq.reverse(); + visitor.visit_seq(Seq { seq }) + } + Value::Unit => visitor.visit_unit(), + } + } + + fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_i64(visitor) + } + + fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_i64(visitor) + } + + fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_i64(visitor) + } + + fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + match self { + Value::Number(Number::Integer(i)) => visitor.visit_i64(i), + v => Err(RonError::custom(format!("Expected a number, got {:?}", v))), + } + } + + fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_u64(visitor) + } + + fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_u64(visitor) + } + + fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + self.deserialize_u64(visitor) + } + + fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value> + where + V: Visitor<'de>, + { + match self { + Value::Number(Number::Integer(i)) => visitor.visit_u64(i as u64), + v => Err(RonError::custom(format!("Expected a number, got {:?}", v))), + } + } +} + +struct MapAccessor { + keys: Vec<Value>, + values: Vec<Value>, +} + +impl<'de> MapAccess<'de> for MapAccessor { + type Error = RonError; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>> + where + K: DeserializeSeed<'de>, + { + // The `Vec` is reversed, so we can pop to get the originally first element + self.keys + .pop() + .map_or(Ok(None), |v| seed.deserialize(v).map(Some)) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value> + where + V: DeserializeSeed<'de>, + { + // The `Vec` is reversed, so we can pop to get the originally first element + self.values + .pop() + .map(|v| seed.deserialize(v)) + .expect("Contract violation") + } +} + +struct Seq { + seq: Vec<Value>, +} + +impl<'de> SeqAccess<'de> for Seq { + type Error = RonError; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>> + where + T: DeserializeSeed<'de>, + { + // The `Vec` is reversed, so we can pop to get the originally first element + self.seq + .pop() + .map_or(Ok(None), |v| seed.deserialize(v).map(Some)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use serde::Deserialize; + use std::{collections::BTreeMap, fmt::Debug}; + + fn assert_same<'de, T>(s: &'de str) + where + T: Debug + Deserialize<'de> + PartialEq, + { + use crate::de::from_str; + + let direct: T = from_str(s).unwrap(); + let value: Value = from_str(s).unwrap(); + let value = T::deserialize(value).unwrap(); + + assert_eq!(direct, value, "Deserialization for {:?} is not the same", s); + } + + #[test] + fn boolean() { + assert_same::<bool>("true"); + assert_same::<bool>("false"); + } + + #[test] + fn float() { + assert_same::<f64>("0.123"); + assert_same::<f64>("-4.19"); + } + + #[test] + fn int() { + assert_same::<u32>("626"); + assert_same::<i32>("-50"); + } + + #[test] + fn char() { + assert_same::<char>("'4'"); + assert_same::<char>("'c'"); + } + + #[test] + fn map() { + assert_same::<BTreeMap<char, String>>( + "{ +'a': \"Hello\", +'b': \"Bye\", + }", + ); + } + + #[test] + fn option() { + assert_same::<Option<char>>("Some('a')"); + assert_same::<Option<char>>("None"); + } + + #[test] + fn seq() { + assert_same::<Vec<f64>>("[1.0, 2.0, 3.0, 4.0]"); + } + + #[test] + fn unit() { + assert_same::<()>("()"); + } +} |