summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ron/src
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/ron/src')
-rw-r--r--third_party/rust/ron/src/de/id.rs244
-rw-r--r--third_party/rust/ron/src/de/mod.rs685
-rw-r--r--third_party/rust/ron/src/de/tag.rs249
-rw-r--r--third_party/rust/ron/src/de/tests.rs328
-rw-r--r--third_party/rust/ron/src/de/value.rs335
-rw-r--r--third_party/rust/ron/src/error.rs164
-rw-r--r--third_party/rust/ron/src/extensions.rs26
-rw-r--r--third_party/rust/ron/src/lib.rs75
-rw-r--r--third_party/rust/ron/src/parse.rs932
-rw-r--r--third_party/rust/ron/src/ser/mod.rs1089
-rw-r--r--third_party/rust/ron/src/ser/value.rs23
-rw-r--r--third_party/rust/ron/src/value.rs553
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] = &empty;
+ 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::<()>("()");
+ }
+}