summaryrefslogtreecommitdiffstats
path: root/third_party/rust/ron/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/rust/ron/src
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/ron/src')
-rw-r--r--third_party/rust/ron/src/de/id.rs246
-rw-r--r--third_party/rust/ron/src/de/mod.rs807
-rw-r--r--third_party/rust/ron/src/de/tag.rs251
-rw-r--r--third_party/rust/ron/src/de/tests.rs362
-rw-r--r--third_party/rust/ron/src/de/value.rs335
-rw-r--r--third_party/rust/ron/src/error.rs404
-rw-r--r--third_party/rust/ron/src/extensions.rs28
-rw-r--r--third_party/rust/ron/src/lib.rs20
-rw-r--r--third_party/rust/ron/src/options.rs183
-rw-r--r--third_party/rust/ron/src/parse.rs978
-rw-r--r--third_party/rust/ron/src/ser/mod.rs996
-rw-r--r--third_party/rust/ron/src/ser/tests.rs146
-rw-r--r--third_party/rust/ron/src/ser/value.rs23
-rw-r--r--third_party/rust/ron/src/value.rs553
14 files changed, 5332 insertions, 0 deletions
diff --git a/third_party/rust/ron/src/de/id.rs b/third_party/rust/ron/src/de/id.rs
new file mode 100644
index 0000000000..537ce5690a
--- /dev/null
+++ b/third_party/rust/ron/src/de/id.rs
@@ -0,0 +1,246 @@
+use serde::de::{self, Visitor};
+
+use super::{Deserializer, Error, Result};
+
+pub struct IdDeserializer<'a, 'b: 'a> {
+ d: &'a mut Deserializer<'b>,
+}
+
+impl<'a, 'b: 'a> IdDeserializer<'a, 'b> {
+ pub fn new(d: &'a mut Deserializer<'b>) -> Self {
+ IdDeserializer { d }
+ }
+}
+
+impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut IdDeserializer<'a, 'b> {
+ type Error = Error;
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_identifier(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.deserialize_identifier(visitor)
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.deserialize_identifier(visitor)
+ }
+
+ fn deserialize_bool<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_i8<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_i16<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_i32<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_i64<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_i128<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_u8<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_u16<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_u32<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_u64<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_u128<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_f32<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_f64<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_char<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_string<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_bytes<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_byte_buf<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_option<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_unit<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_unit_struct<V>(self, _: &'static str, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_newtype_struct<V>(self, _: &'static str, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_seq<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_tuple<V>(self, _: usize, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_map<V>(self, _: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _: &'static str,
+ _: &'static [&'static str],
+ _: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _: &'static str,
+ _: &'static [&'static str],
+ _: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ unimplemented!("IdDeserializer may only be used for identifiers")
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.deserialize_any(visitor)
+ }
+}
diff --git a/third_party/rust/ron/src/de/mod.rs b/third_party/rust/ron/src/de/mod.rs
new file mode 100644
index 0000000000..0920a67b43
--- /dev/null
+++ b/third_party/rust/ron/src/de/mod.rs
@@ -0,0 +1,807 @@
+/// Deserialization module.
+pub use crate::error::{Error, Position, SpannedError};
+
+use serde::de::{self, DeserializeSeed, Deserializer as SerdeError, Visitor};
+use std::{borrow::Cow, io, str};
+
+use self::{id::IdDeserializer, tag::TagDeserializer};
+use crate::{
+ error::{Result, SpannedResult},
+ extensions::Extensions,
+ options::Options,
+ parse::{AnyNum, Bytes, ParsedStr},
+};
+
+mod id;
+mod tag;
+#[cfg(test)]
+mod tests;
+mod value;
+
+/// The RON deserializer.
+///
+/// If you just want to simply deserialize a value,
+/// you can use the `from_str` convenience function.
+pub struct Deserializer<'de> {
+ bytes: Bytes<'de>,
+ newtype_variant: bool,
+ last_identifier: Option<&'de str>,
+}
+
+impl<'de> Deserializer<'de> {
+ // Cannot implement trait here since output is tied to input lifetime 'de.
+ #[allow(clippy::should_implement_trait)]
+ pub fn from_str(input: &'de str) -> SpannedResult<Self> {
+ Self::from_str_with_options(input, Options::default())
+ }
+
+ pub fn from_bytes(input: &'de [u8]) -> SpannedResult<Self> {
+ Self::from_bytes_with_options(input, Options::default())
+ }
+
+ pub fn from_str_with_options(input: &'de str, options: Options) -> SpannedResult<Self> {
+ Self::from_bytes_with_options(input.as_bytes(), options)
+ }
+
+ pub fn from_bytes_with_options(input: &'de [u8], options: Options) -> SpannedResult<Self> {
+ let mut deserializer = Deserializer {
+ bytes: Bytes::new(input)?,
+ newtype_variant: false,
+ last_identifier: None,
+ };
+
+ deserializer.bytes.exts |= options.default_extensions;
+
+ Ok(deserializer)
+ }
+
+ pub fn remainder(&self) -> Cow<'_, str> {
+ String::from_utf8_lossy(self.bytes.bytes())
+ }
+
+ pub fn span_error(&self, code: Error) -> SpannedError {
+ self.bytes.span_error(code)
+ }
+}
+
+/// A convenience function for building a deserializer
+/// and deserializing a value of type `T` from a reader.
+pub fn from_reader<R, T>(rdr: R) -> SpannedResult<T>
+where
+ R: io::Read,
+ T: de::DeserializeOwned,
+{
+ Options::default().from_reader(rdr)
+}
+
+/// A convenience function for building a deserializer
+/// and deserializing a value of type `T` from a string.
+pub fn from_str<'a, T>(s: &'a str) -> SpannedResult<T>
+where
+ T: de::Deserialize<'a>,
+{
+ Options::default().from_str(s)
+}
+
+/// A convenience function for building a deserializer
+/// and deserializing a value of type `T` from bytes.
+pub fn from_bytes<'a, T>(s: &'a [u8]) -> SpannedResult<T>
+where
+ T: de::Deserialize<'a>,
+{
+ Options::default().from_bytes(s)
+}
+
+impl<'de> Deserializer<'de> {
+ /// Check if the remaining bytes are whitespace only,
+ /// otherwise return an error.
+ pub fn end(&mut self) -> Result<()> {
+ self.bytes.skip_ws()?;
+
+ if self.bytes.bytes().is_empty() {
+ Ok(())
+ } else {
+ Err(Error::TrailingCharacters)
+ }
+ }
+
+ /// Called from `deserialize_any` when a struct was detected. Decides if
+ /// there is a unit, tuple or usual struct and deserializes it
+ /// accordingly.
+ ///
+ /// This method assumes there is no identifier left.
+ fn handle_any_struct<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ // Create a working copy
+ let mut bytes = self.bytes;
+
+ if bytes.consume("(") {
+ bytes.skip_ws()?;
+
+ if bytes.check_tuple_struct()? {
+ // first argument is technically incorrect, but ignored anyway
+ self.deserialize_tuple(0, visitor)
+ } else {
+ // first two arguments are technically incorrect, but ignored anyway
+ self.deserialize_struct("", &[], visitor)
+ }
+ } else {
+ visitor.visit_unit()
+ }
+ }
+}
+
+impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ // Newtype variants can only be unwrapped if we receive information
+ // about the wrapped type - with `deserialize_any` we don't
+ self.newtype_variant = false;
+
+ if self.bytes.consume_ident("true") {
+ return visitor.visit_bool(true);
+ } else if self.bytes.consume_ident("false") {
+ return visitor.visit_bool(false);
+ } else if self.bytes.check_ident("Some") {
+ return self.deserialize_option(visitor);
+ } else if self.bytes.consume_ident("None") {
+ return visitor.visit_none();
+ } else if self.bytes.consume("()") {
+ return visitor.visit_unit();
+ } else if self.bytes.consume_ident("inf") {
+ return visitor.visit_f64(std::f64::INFINITY);
+ } else if self.bytes.consume_ident("-inf") {
+ return visitor.visit_f64(std::f64::NEG_INFINITY);
+ } else if self.bytes.consume_ident("NaN") {
+ return visitor.visit_f64(std::f64::NAN);
+ }
+
+ // `identifier` does not change state if it fails
+ let ident = self.bytes.identifier().ok();
+
+ if ident.is_some() {
+ self.bytes.skip_ws()?;
+
+ return self.handle_any_struct(visitor);
+ }
+
+ match self.bytes.peek_or_eof()? {
+ b'(' => self.handle_any_struct(visitor),
+ b'[' => self.deserialize_seq(visitor),
+ b'{' => self.deserialize_map(visitor),
+ b'0'..=b'9' | b'+' | b'-' => {
+ let any_num: AnyNum = self.bytes.any_num()?;
+
+ match any_num {
+ AnyNum::F32(x) => visitor.visit_f32(x),
+ AnyNum::F64(x) => visitor.visit_f64(x),
+ AnyNum::I8(x) => visitor.visit_i8(x),
+ AnyNum::U8(x) => visitor.visit_u8(x),
+ AnyNum::I16(x) => visitor.visit_i16(x),
+ AnyNum::U16(x) => visitor.visit_u16(x),
+ AnyNum::I32(x) => visitor.visit_i32(x),
+ AnyNum::U32(x) => visitor.visit_u32(x),
+ AnyNum::I64(x) => visitor.visit_i64(x),
+ AnyNum::U64(x) => visitor.visit_u64(x),
+ #[cfg(feature = "integer128")]
+ AnyNum::I128(x) => visitor.visit_i128(x),
+ #[cfg(feature = "integer128")]
+ AnyNum::U128(x) => visitor.visit_u128(x),
+ }
+ }
+ b'.' => self.deserialize_f64(visitor),
+ b'"' | b'r' => self.deserialize_string(visitor),
+ b'\'' => self.deserialize_char(visitor),
+ other => Err(Error::UnexpectedByte(other as char)),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_bool(self.bytes.bool()?)
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_i8(self.bytes.signed_integer()?)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_i16(self.bytes.signed_integer()?)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_i32(self.bytes.signed_integer()?)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_i64(self.bytes.signed_integer()?)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_i128(self.bytes.signed_integer()?)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_u8(self.bytes.unsigned_integer()?)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_u16(self.bytes.unsigned_integer()?)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_u32(self.bytes.unsigned_integer()?)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_u64(self.bytes.unsigned_integer()?)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_u128(self.bytes.unsigned_integer()?)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_f32(self.bytes.float()?)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_f64(self.bytes.float()?)
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_char(self.bytes.char()?)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ match self.bytes.string()? {
+ ParsedStr::Allocated(s) => visitor.visit_string(s),
+ ParsedStr::Slice(s) => visitor.visit_borrowed_str(s),
+ }
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let res = {
+ let string = self.bytes.string()?;
+ let base64_str = match string {
+ ParsedStr::Allocated(ref s) => s.as_str(),
+ ParsedStr::Slice(s) => s,
+ };
+ base64::decode(base64_str)
+ };
+
+ match res {
+ Ok(byte_buf) => visitor.visit_byte_buf(byte_buf),
+ Err(err) => Err(Error::Base64Error(err)),
+ }
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if self.bytes.consume("None") {
+ visitor.visit_none()
+ } else if self.bytes.consume("Some") && {
+ self.bytes.skip_ws()?;
+ self.bytes.consume("(")
+ } {
+ self.bytes.skip_ws()?;
+
+ let v = visitor.visit_some(&mut *self)?;
+
+ self.bytes.skip_ws()?;
+
+ if self.bytes.consume(")") {
+ Ok(v)
+ } else {
+ Err(Error::ExpectedOptionEnd)
+ }
+ } else if self.bytes.exts.contains(Extensions::IMPLICIT_SOME) {
+ visitor.visit_some(&mut *self)
+ } else {
+ Err(Error::ExpectedOption)
+ }
+ }
+
+ // In Serde, unit means an anonymous value containing no data.
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if self.newtype_variant || self.bytes.consume("()") {
+ self.newtype_variant = false;
+
+ visitor.visit_unit()
+ } else {
+ Err(Error::ExpectedUnit)
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if self.newtype_variant || self.bytes.consume_struct_name(name)? {
+ self.newtype_variant = false;
+
+ visitor.visit_unit()
+ } else {
+ self.deserialize_unit(visitor)
+ }
+ }
+
+ fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if self.bytes.exts.contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
+ self.newtype_variant = false;
+
+ return visitor.visit_newtype_struct(&mut *self);
+ }
+
+ self.bytes.consume_struct_name(name)?;
+
+ self.bytes.skip_ws()?;
+
+ if self.bytes.consume("(") {
+ self.bytes.skip_ws()?;
+ let value = visitor.visit_newtype_struct(&mut *self)?;
+ self.bytes.comma()?;
+
+ if self.bytes.consume(")") {
+ Ok(value)
+ } else {
+ Err(Error::ExpectedStructLikeEnd)
+ }
+ } else if name.is_empty() {
+ Err(Error::ExpectedStructLike)
+ } else {
+ Err(Error::ExpectedNamedStructLike(name))
+ }
+ }
+
+ fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.newtype_variant = false;
+
+ if self.bytes.consume("[") {
+ let value = visitor.visit_seq(CommaSeparated::new(b']', self))?;
+ self.bytes.comma()?;
+
+ if self.bytes.consume("]") {
+ Ok(value)
+ } else {
+ Err(Error::ExpectedArrayEnd)
+ }
+ } else {
+ Err(Error::ExpectedArray)
+ }
+ }
+
+ fn deserialize_tuple<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if self.newtype_variant || self.bytes.consume("(") {
+ let old_newtype_variant = self.newtype_variant;
+ self.newtype_variant = false;
+
+ let value = visitor.visit_seq(CommaSeparated::new(b')', self))?;
+ self.bytes.comma()?;
+
+ if old_newtype_variant || self.bytes.consume(")") {
+ Ok(value)
+ } else {
+ Err(Error::ExpectedStructLikeEnd)
+ }
+ } else {
+ Err(Error::ExpectedStructLike)
+ }
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ name: &'static str,
+ len: usize,
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if !self.newtype_variant {
+ self.bytes.consume_struct_name(name)?;
+ }
+
+ self.deserialize_tuple(len, visitor).map_err(|e| match e {
+ Error::ExpectedStructLike if !name.is_empty() => Error::ExpectedNamedStructLike(name),
+ e => e,
+ })
+ }
+
+ fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.newtype_variant = false;
+
+ if self.bytes.consume("{") {
+ let value = visitor.visit_map(CommaSeparated::new(b'}', self))?;
+ self.bytes.comma()?;
+
+ if self.bytes.consume("}") {
+ Ok(value)
+ } else {
+ Err(Error::ExpectedMapEnd)
+ }
+ } else {
+ Err(Error::ExpectedMap)
+ }
+ }
+
+ fn deserialize_struct<V>(
+ mut self,
+ name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ if !self.newtype_variant {
+ self.bytes.consume_struct_name(name)?;
+ }
+
+ self.bytes.skip_ws()?;
+
+ if self.newtype_variant || self.bytes.consume("(") {
+ let old_newtype_variant = self.newtype_variant;
+ self.newtype_variant = false;
+
+ let value = visitor
+ .visit_map(CommaSeparated::new(b')', self))
+ .map_err(|err| {
+ struct_error_name(
+ err,
+ if !old_newtype_variant && !name.is_empty() {
+ Some(name)
+ } else {
+ None
+ },
+ )
+ })?;
+
+ self.bytes.comma()?;
+
+ if old_newtype_variant || self.bytes.consume(")") {
+ Ok(value)
+ } else {
+ Err(Error::ExpectedStructLikeEnd)
+ }
+ } else if name.is_empty() {
+ Err(Error::ExpectedStructLike)
+ } else {
+ Err(Error::ExpectedNamedStructLike(name))
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.newtype_variant = false;
+
+ match visitor.visit_enum(Enum::new(self)) {
+ Ok(value) => Ok(value),
+ Err(Error::NoSuchEnumVariant {
+ expected,
+ found,
+ outer: None,
+ }) if !name.is_empty() => Err(Error::NoSuchEnumVariant {
+ expected,
+ found,
+ outer: Some(String::from(name)),
+ }),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let identifier = str::from_utf8(self.bytes.identifier()?).map_err(Error::from)?;
+
+ self.last_identifier = Some(identifier);
+
+ visitor.visit_str(identifier)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_any(visitor)
+ }
+}
+
+struct CommaSeparated<'a, 'de: 'a> {
+ de: &'a mut Deserializer<'de>,
+ terminator: u8,
+ had_comma: bool,
+}
+
+impl<'a, 'de> CommaSeparated<'a, 'de> {
+ fn new(terminator: u8, de: &'a mut Deserializer<'de>) -> Self {
+ CommaSeparated {
+ de,
+ terminator,
+ had_comma: true,
+ }
+ }
+
+ fn has_element(&mut self) -> Result<bool> {
+ self.de.bytes.skip_ws()?;
+
+ match (
+ self.had_comma,
+ self.de.bytes.peek_or_eof()? != self.terminator,
+ ) {
+ // Trailing comma, maybe has a next element
+ (true, has_element) => Ok(has_element),
+ // No trailing comma but terminator
+ (false, false) => Ok(false),
+ // No trailing comma or terminator
+ (false, true) => Err(Error::ExpectedComma),
+ }
+ }
+}
+
+impl<'de, 'a> de::SeqAccess<'de> for CommaSeparated<'a, 'de> {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ if self.has_element()? {
+ let res = seed.deserialize(&mut *self.de)?;
+
+ self.had_comma = self.de.bytes.comma()?;
+
+ Ok(Some(res))
+ } else {
+ Ok(None)
+ }
+ }
+}
+
+impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: DeserializeSeed<'de>,
+ {
+ if self.has_element()? {
+ if self.terminator == b')' {
+ seed.deserialize(&mut IdDeserializer::new(&mut *self.de))
+ .map(Some)
+ } else {
+ seed.deserialize(&mut *self.de).map(Some)
+ }
+ } else {
+ Ok(None)
+ }
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ self.de.bytes.skip_ws()?;
+
+ if self.de.bytes.consume(":") {
+ self.de.bytes.skip_ws()?;
+
+ let res = seed.deserialize(&mut TagDeserializer::new(&mut *self.de))?;
+
+ self.had_comma = self.de.bytes.comma()?;
+
+ Ok(res)
+ } else {
+ Err(Error::ExpectedMapColon)
+ }
+ }
+}
+
+struct Enum<'a, 'de: 'a> {
+ de: &'a mut Deserializer<'de>,
+}
+
+impl<'a, 'de> Enum<'a, 'de> {
+ fn new(de: &'a mut Deserializer<'de>) -> Self {
+ Enum { de }
+ }
+}
+
+impl<'de, 'a> de::EnumAccess<'de> for Enum<'a, 'de> {
+ type Error = Error;
+ type Variant = Self;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ self.de.bytes.skip_ws()?;
+
+ let value = seed.deserialize(&mut *self.de)?;
+
+ Ok((value, self))
+ }
+}
+
+impl<'de, 'a> de::VariantAccess<'de> for Enum<'a, 'de> {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ let newtype_variant = self.de.last_identifier;
+
+ self.de.bytes.skip_ws()?;
+
+ if self.de.bytes.consume("(") {
+ self.de.bytes.skip_ws()?;
+
+ self.de.newtype_variant = self
+ .de
+ .bytes
+ .exts
+ .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
+
+ let val = seed
+ .deserialize(&mut *self.de)
+ .map_err(|err| struct_error_name(err, newtype_variant))?;
+
+ self.de.newtype_variant = false;
+
+ self.de.bytes.comma()?;
+
+ if self.de.bytes.consume(")") {
+ Ok(val)
+ } else {
+ Err(Error::ExpectedStructLikeEnd)
+ }
+ } else {
+ Err(Error::ExpectedStructLike)
+ }
+ }
+
+ fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de.bytes.skip_ws()?;
+
+ self.de.deserialize_tuple(len, visitor)
+ }
+
+ fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let struct_variant = self.de.last_identifier;
+
+ self.de.bytes.skip_ws()?;
+
+ self.de
+ .deserialize_struct("", fields, visitor)
+ .map_err(|err| struct_error_name(err, struct_variant))
+ }
+}
+
+fn struct_error_name(error: Error, name: Option<&str>) -> Error {
+ match error {
+ Error::NoSuchStructField {
+ expected,
+ found,
+ outer: None,
+ } => Error::NoSuchStructField {
+ expected,
+ found,
+ outer: name.map(ToOwned::to_owned),
+ },
+ Error::MissingStructField { field, outer: None } => Error::MissingStructField {
+ field,
+ outer: name.map(ToOwned::to_owned),
+ },
+ Error::DuplicateStructField { field, outer: None } => Error::DuplicateStructField {
+ field,
+ outer: name.map(ToOwned::to_owned),
+ },
+ e => e,
+ }
+}
diff --git a/third_party/rust/ron/src/de/tag.rs b/third_party/rust/ron/src/de/tag.rs
new file mode 100644
index 0000000000..9e204ff847
--- /dev/null
+++ b/third_party/rust/ron/src/de/tag.rs
@@ -0,0 +1,251 @@
+use serde::de::{self, Visitor};
+
+use super::{Deserializer, Error, Result};
+
+pub struct TagDeserializer<'a, 'b: 'a> {
+ d: &'a mut Deserializer<'b>,
+}
+
+impl<'a, 'b: 'a> TagDeserializer<'a, 'b> {
+ pub fn new(d: &'a mut Deserializer<'b>) -> Self {
+ TagDeserializer { d }
+ }
+}
+
+impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut TagDeserializer<'a, 'b> {
+ type Error = Error;
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_str(visitor)
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_any(visitor)
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_bool(visitor)
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_i8(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_i16(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_i32(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_i64(visitor)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_i128(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_u8(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_u16(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_u32(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_u64(visitor)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_u128(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_f32(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_f64(visitor)
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_char(visitor)
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_string(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_bytes(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_option(visitor)
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_unit(visitor)
+ }
+
+ fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_unit_struct(name, visitor)
+ }
+
+ fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_newtype_struct(name, visitor)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_tuple(len, visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ name: &'static str,
+ len: usize,
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_tuple_struct(name, len, visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_map(visitor)
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_struct(name, fields, visitor)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_enum(name, variants, visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'b>,
+ {
+ self.d.deserialize_ignored_any(visitor)
+ }
+}
diff --git a/third_party/rust/ron/src/de/tests.rs b/third_party/rust/ron/src/de/tests.rs
new file mode 100644
index 0000000000..3e37e4e9db
--- /dev/null
+++ b/third_party/rust/ron/src/de/tests.rs
@@ -0,0 +1,362 @@
+use serde::Deserialize;
+use serde_bytes;
+
+use crate::{
+ de::from_str,
+ error::{Error, Position, SpannedError, SpannedResult},
+ parse::{AnyNum, Bytes},
+};
+
+#[derive(Debug, PartialEq, Deserialize)]
+struct EmptyStruct1;
+
+#[derive(Debug, PartialEq, Deserialize)]
+struct EmptyStruct2 {}
+
+#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
+struct MyStruct {
+ x: f32,
+ y: f32,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Deserialize)]
+enum MyEnum {
+ A,
+ B(bool),
+ C(bool, f32),
+ D { a: i32, b: i32 },
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct BytesStruct {
+ small: Vec<u8>,
+ #[serde(with = "serde_bytes")]
+ large: Vec<u8>,
+}
+
+#[test]
+fn test_empty_struct() {
+ assert_eq!(Ok(EmptyStruct1), from_str("EmptyStruct1"));
+ assert_eq!(Ok(EmptyStruct2 {}), from_str("EmptyStruct2()"));
+}
+
+#[test]
+fn test_struct() {
+ let my_struct = MyStruct { x: 4.0, y: 7.0 };
+
+ assert_eq!(Ok(my_struct), from_str("MyStruct(x:4,y:7,)"));
+ assert_eq!(Ok(my_struct), from_str("(x:4,y:7)"));
+
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct NewType(i32);
+
+ assert_eq!(Ok(NewType(42)), from_str("NewType(42)"));
+ assert_eq!(Ok(NewType(33)), from_str("(33)"));
+
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct TupleStruct(f32, f32);
+
+ assert_eq!(Ok(TupleStruct(2.0, 5.0)), from_str("TupleStruct(2,5,)"));
+ assert_eq!(Ok(TupleStruct(3.0, 4.0)), from_str("(3,4)"));
+}
+
+#[test]
+fn test_option() {
+ assert_eq!(Ok(Some(1u8)), from_str("Some(1)"));
+ assert_eq!(Ok(None::<u8>), from_str("None"));
+}
+
+#[test]
+fn test_enum() {
+ assert_eq!(Ok(MyEnum::A), from_str("A"));
+ assert_eq!(Ok(MyEnum::B(true)), from_str("B(true,)"));
+ assert_eq!(Ok(MyEnum::C(true, 3.5)), from_str("C(true,3.5,)"));
+ assert_eq!(Ok(MyEnum::D { a: 2, b: 3 }), from_str("D(a:2,b:3,)"));
+}
+
+#[test]
+fn test_array() {
+ let empty: [i32; 0] = [];
+ assert_eq!(Ok(empty), from_str("()"));
+ let empty_array = empty.to_vec();
+ assert_eq!(Ok(empty_array), from_str("[]"));
+
+ assert_eq!(Ok([2, 3, 4i32]), from_str("(2,3,4,)"));
+ assert_eq!(Ok([2, 3, 4i32].to_vec()), from_str("[2,3,4,]"));
+}
+
+#[test]
+fn test_map() {
+ use std::collections::HashMap;
+
+ let mut map = HashMap::new();
+ map.insert((true, false), 4);
+ map.insert((false, false), 123);
+
+ assert_eq!(
+ Ok(map),
+ from_str(
+ "{
+ (true,false,):4,
+ (false,false,):123,
+ }"
+ )
+ );
+}
+
+#[test]
+fn test_string() {
+ let s: String = from_str("\"String\"").unwrap();
+ assert_eq!("String", s);
+
+ let raw: String = from_str("r\"String\"").unwrap();
+ assert_eq!("String", raw);
+
+ let raw_hashes: String = from_str("r#\"String\"#").unwrap();
+ assert_eq!("String", raw_hashes);
+
+ let raw_hashes_multiline: String = from_str("r#\"String with\nmultiple\nlines\n\"#").unwrap();
+ assert_eq!("String with\nmultiple\nlines\n", raw_hashes_multiline);
+
+ let raw_hashes_quote: String = from_str("r##\"String with \"#\"##").unwrap();
+ assert_eq!("String with \"#", raw_hashes_quote);
+}
+
+#[test]
+fn test_char() {
+ assert_eq!(Ok('c'), from_str("'c'"));
+}
+
+#[test]
+fn test_escape_char() {
+ assert_eq!('\'', from_str::<char>("'\\''").unwrap());
+}
+
+#[test]
+fn test_escape() {
+ assert_eq!("\"Quoted\"", from_str::<String>(r#""\"Quoted\"""#).unwrap());
+}
+
+#[test]
+fn test_comment() {
+ assert_eq!(
+ MyStruct { x: 1.0, y: 2.0 },
+ from_str(
+ "(
+x: 1.0, // x is just 1
+// There is another comment in the very next line..
+// And y is indeed
+y: 2.0 // 2!
+ )"
+ )
+ .unwrap()
+ );
+}
+
+fn err<T>(kind: Error, line: usize, col: usize) -> SpannedResult<T> {
+ Err(SpannedError {
+ code: kind,
+ position: Position { line, col },
+ })
+}
+
+#[test]
+fn test_err_wrong_value() {
+ use self::Error::*;
+ use std::collections::HashMap;
+
+ assert_eq!(from_str::<f32>("'c'"), err(ExpectedFloat, 1, 1));
+ assert_eq!(from_str::<String>("'c'"), err(ExpectedString, 1, 1));
+ assert_eq!(from_str::<HashMap<u32, u32>>("'c'"), err(ExpectedMap, 1, 1));
+ assert_eq!(from_str::<[u8; 5]>("'c'"), err(ExpectedStructLike, 1, 1));
+ assert_eq!(from_str::<Vec<u32>>("'c'"), err(ExpectedArray, 1, 1));
+ assert_eq!(from_str::<MyEnum>("'c'"), err(ExpectedIdentifier, 1, 1));
+ assert_eq!(
+ from_str::<MyStruct>("'c'"),
+ err(ExpectedNamedStructLike("MyStruct"), 1, 1)
+ );
+ assert_eq!(
+ from_str::<MyStruct>("NotMyStruct(x: 4, y: 2)"),
+ err(
+ ExpectedDifferentStructName {
+ expected: "MyStruct",
+ found: String::from("NotMyStruct")
+ },
+ 1,
+ 12
+ )
+ );
+ assert_eq!(from_str::<(u8, bool)>("'c'"), err(ExpectedStructLike, 1, 1));
+ assert_eq!(from_str::<bool>("notabool"), err(ExpectedBoolean, 1, 1));
+
+ assert_eq!(
+ from_str::<MyStruct>("MyStruct(\n x: true)"),
+ err(ExpectedFloat, 2, 8)
+ );
+ assert_eq!(
+ from_str::<MyStruct>("MyStruct(\n x: 3.5, \n y:)"),
+ err(ExpectedFloat, 3, 7)
+ );
+}
+
+#[test]
+fn test_perm_ws() {
+ assert_eq!(
+ from_str::<MyStruct>("\nMyStruct \t ( \n x : 3.5 , \t y\n: 4.5 \n ) \t\n"),
+ Ok(MyStruct { x: 3.5, y: 4.5 })
+ );
+}
+
+#[test]
+fn untagged() {
+ #[derive(Deserialize, Debug, PartialEq)]
+ #[serde(untagged)]
+ enum Untagged {
+ U8(u8),
+ Bool(bool),
+ }
+
+ assert_eq!(from_str::<Untagged>("true").unwrap(), Untagged::Bool(true));
+ assert_eq!(from_str::<Untagged>("8").unwrap(), Untagged::U8(8));
+}
+
+#[test]
+fn rename() {
+ #[derive(Deserialize, Debug, PartialEq)]
+ enum Foo {
+ #[serde(rename = "2d")]
+ D2,
+ #[serde(rename = "triangle-list")]
+ TriangleList,
+ }
+ assert_eq!(from_str::<Foo>("r#2d").unwrap(), Foo::D2);
+ assert_eq!(
+ from_str::<Foo>("r#triangle-list").unwrap(),
+ Foo::TriangleList
+ );
+}
+
+#[test]
+fn forgot_apostrophes() {
+ let de: SpannedResult<(i32, String)> = from_str("(4, \"Hello)");
+
+ assert!(matches!(
+ de,
+ Err(SpannedError {
+ code: Error::ExpectedStringEnd,
+ position: _,
+ })
+ ));
+}
+
+#[test]
+fn expected_attribute() {
+ let de: SpannedResult<String> = from_str("#\"Hello\"");
+
+ assert_eq!(de, err(Error::ExpectedAttribute, 1, 2));
+}
+
+#[test]
+fn expected_attribute_end() {
+ let de: SpannedResult<String> = from_str("#![enable(unwrap_newtypes) \"Hello\"");
+
+ assert_eq!(de, err(Error::ExpectedAttributeEnd, 1, 28));
+}
+
+#[test]
+fn invalid_attribute() {
+ let de: SpannedResult<String> = from_str("#![enable(invalid)] \"Hello\"");
+
+ assert_eq!(
+ de,
+ err(Error::NoSuchExtension("invalid".to_string()), 1, 18)
+ );
+}
+
+#[test]
+fn multiple_attributes() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct New(String);
+ let de: SpannedResult<New> =
+ from_str("#![enable(unwrap_newtypes)] #![enable(unwrap_newtypes)] \"Hello\"");
+
+ assert_eq!(de, Ok(New("Hello".to_owned())));
+}
+
+#[test]
+fn uglified_attribute() {
+ let de: SpannedResult<()> = from_str(
+ "# !\
+ // We definitely want to add a comment here
+ [\t\tenable( // best style ever
+ unwrap_newtypes ) ] ()",
+ );
+
+ assert_eq!(de, Ok(()));
+}
+
+#[test]
+fn implicit_some() {
+ use serde::de::DeserializeOwned;
+
+ fn de<T: DeserializeOwned>(s: &str) -> Option<T> {
+ let enable = "#![enable(implicit_some)]\n".to_string();
+
+ from_str::<Option<T>>(&(enable + s)).unwrap()
+ }
+
+ assert_eq!(de("'c'"), Some('c'));
+ assert_eq!(de("5"), Some(5));
+ assert_eq!(de("\"Hello\""), Some("Hello".to_owned()));
+ assert_eq!(de("false"), Some(false));
+ assert_eq!(
+ de("MyStruct(x: .4, y: .5)"),
+ Some(MyStruct { x: 0.4, y: 0.5 })
+ );
+
+ assert_eq!(de::<char>("None"), None);
+
+ // Not concise
+ assert_eq!(de::<Option<Option<char>>>("None"), None);
+}
+
+#[test]
+fn ws_tuple_newtype_variant() {
+ assert_eq!(Ok(MyEnum::B(true)), from_str("B ( \n true \n ) "));
+}
+
+#[test]
+fn test_byte_stream() {
+ assert_eq!(
+ Ok(BytesStruct {
+ small: vec![1, 2],
+ large: vec![1, 2, 3, 4]
+ }),
+ from_str("BytesStruct( small:[1, 2], large:\"AQIDBA==\" )"),
+ );
+}
+
+#[test]
+fn test_numbers() {
+ assert_eq!(
+ Ok(vec![1234, 12345, 123456, 1234567, 555_555]),
+ from_str("[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]"),
+ );
+}
+
+fn de_any_number(s: &str) -> AnyNum {
+ let mut bytes = Bytes::new(s.as_bytes()).unwrap();
+
+ bytes.any_num().unwrap()
+}
+
+#[test]
+fn test_any_number_precision() {
+ assert_eq!(de_any_number("1"), AnyNum::U8(1));
+ assert_eq!(de_any_number("+1"), AnyNum::I8(1));
+ assert_eq!(de_any_number("-1"), AnyNum::I8(-1));
+ assert_eq!(de_any_number("-1.0"), AnyNum::F32(-1.0));
+ assert_eq!(de_any_number("1."), AnyNum::F32(1.));
+ assert_eq!(de_any_number("-1."), AnyNum::F32(-1.));
+ assert_eq!(de_any_number("0.3"), AnyNum::F64(0.3));
+}
diff --git a/third_party/rust/ron/src/de/value.rs b/third_party/rust/ron/src/de/value.rs
new file mode 100644
index 0000000000..544ee05e37
--- /dev/null
+++ b/third_party/rust/ron/src/de/value.rs
@@ -0,0 +1,335 @@
+use std::fmt;
+
+use serde::{
+ de::{Error, MapAccess, SeqAccess, Visitor},
+ Deserialize, Deserializer,
+};
+
+use crate::error::SpannedResult;
+use crate::value::{Map, Number, Value};
+
+impl std::str::FromStr for Value {
+ type Err = crate::error::SpannedError;
+
+ /// Creates a value from a string reference.
+ fn from_str(s: &str) -> SpannedResult<Self> {
+ let mut de = super::Deserializer::from_str(s)?;
+
+ let val = Value::deserialize(&mut de).map_err(|e| de.span_error(e))?;
+ de.end().map_err(|e| de.span_error(e))?;
+
+ Ok(val)
+ }
+}
+
+impl<'de> Deserialize<'de> for Value {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+struct ValueVisitor;
+
+impl<'de> Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "a RON value")
+ }
+
+ fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Bool(v))
+ }
+
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Number(Number::new(v)))
+ }
+
+ #[cfg(feature = "integer128")]
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_f64(v as f64)
+ }
+
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Number(Number::new(v)))
+ }
+
+ #[cfg(feature = "integer128")]
+ fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_f64(v as f64)
+ }
+
+ fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Number(Number::new(v)))
+ }
+
+ fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Char(v))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_string(v.to_owned())
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::String(v))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_byte_buf(v.to_vec())
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_string(String::from_utf8(v).map_err(|e| Error::custom(format!("{}", e)))?)
+ }
+
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Option(None))
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Value::Option(Some(Box::new(
+ deserializer.deserialize_any(ValueVisitor)?,
+ ))))
+ }
+
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Value::Unit)
+ }
+
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_any(ValueVisitor)
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+ if let Some(cap) = seq.size_hint() {
+ vec.reserve_exact(cap);
+ }
+
+ while let Some(x) = seq.next_element()? {
+ vec.push(x);
+ }
+
+ Ok(Value::Seq(vec))
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut res: Map = Map::new();
+
+ while let Some(entry) = map.next_entry()? {
+ res.insert(entry.0, entry.1);
+ }
+
+ Ok(Value::Map(res))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::str::FromStr;
+
+ fn eval(s: &str) -> Value {
+ s.parse().expect("Failed to parse")
+ }
+
+ #[test]
+ fn test_none() {
+ assert_eq!(eval("None"), Value::Option(None));
+ }
+
+ #[test]
+ fn test_some() {
+ assert_eq!(eval("Some(())"), Value::Option(Some(Box::new(Value::Unit))));
+ assert_eq!(
+ eval("Some ( () )"),
+ Value::Option(Some(Box::new(Value::Unit)))
+ );
+ }
+
+ #[test]
+ fn test_tuples_basic() {
+ assert_eq!(
+ eval("(3, 4.0, 5.0)"),
+ Value::Seq(vec![
+ Value::Number(Number::new(3)),
+ Value::Number(Number::new(4.0)),
+ Value::Number(Number::new(5.0)),
+ ],),
+ );
+ }
+
+ #[test]
+ fn test_tuples_ident() {
+ assert_eq!(
+ eval("(true, 3, 4, 5.0)"),
+ Value::Seq(vec![
+ Value::Bool(true),
+ Value::Number(Number::new(3)),
+ Value::Number(Number::new(4)),
+ Value::Number(Number::new(5.0)),
+ ]),
+ );
+ }
+
+ #[test]
+ fn test_tuples_error() {
+ use crate::de::{Error, Position, SpannedError};
+
+ assert_eq!(
+ Value::from_str("Foo:").unwrap_err(),
+ SpannedError {
+ code: Error::TrailingCharacters,
+ position: Position { col: 4, line: 1 }
+ },
+ );
+ }
+
+ #[test]
+ fn test_floats() {
+ assert_eq!(
+ eval("(inf, -inf, NaN)"),
+ Value::Seq(vec![
+ Value::Number(Number::new(std::f64::INFINITY)),
+ Value::Number(Number::new(std::f64::NEG_INFINITY)),
+ Value::Number(Number::new(std::f64::NAN)),
+ ]),
+ );
+ }
+
+ #[test]
+ fn test_complex() {
+ assert_eq!(
+ eval(
+ "Some([
+ Room ( width: 20, height: 5, name: \"The Room\" ),
+
+ (
+ width: 10.0,
+ height: 10.0,
+ name: \"Another room\",
+ enemy_levels: {
+ \"Enemy1\": 3,
+ \"Enemy2\": 5,
+ \"Enemy3\": 7,
+ },
+ ),
+])"
+ ),
+ Value::Option(Some(Box::new(Value::Seq(vec![
+ Value::Map(
+ vec![
+ (
+ Value::String("width".to_owned()),
+ Value::Number(Number::new(20)),
+ ),
+ (
+ Value::String("height".to_owned()),
+ Value::Number(Number::new(5)),
+ ),
+ (
+ Value::String("name".to_owned()),
+ Value::String("The Room".to_owned()),
+ ),
+ ]
+ .into_iter()
+ .collect(),
+ ),
+ Value::Map(
+ vec![
+ (
+ Value::String("width".to_owned()),
+ Value::Number(Number::new(10.0)),
+ ),
+ (
+ Value::String("height".to_owned()),
+ Value::Number(Number::new(10.0)),
+ ),
+ (
+ Value::String("name".to_owned()),
+ Value::String("Another room".to_owned()),
+ ),
+ (
+ Value::String("enemy_levels".to_owned()),
+ Value::Map(
+ vec![
+ (
+ Value::String("Enemy1".to_owned()),
+ Value::Number(Number::new(3)),
+ ),
+ (
+ Value::String("Enemy2".to_owned()),
+ Value::Number(Number::new(5)),
+ ),
+ (
+ Value::String("Enemy3".to_owned()),
+ Value::Number(Number::new(7)),
+ ),
+ ]
+ .into_iter()
+ .collect(),
+ ),
+ ),
+ ]
+ .into_iter()
+ .collect(),
+ ),
+ ]))))
+ );
+ }
+}
diff --git a/third_party/rust/ron/src/error.rs b/third_party/rust/ron/src/error.rs
new file mode 100644
index 0000000000..7f7cc9b93e
--- /dev/null
+++ b/third_party/rust/ron/src/error.rs
@@ -0,0 +1,404 @@
+use serde::{de, ser};
+use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
+
+/// This type represents all possible errors that can occur when
+/// serializing or deserializing RON data.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct SpannedError {
+ pub code: Error,
+ pub position: Position,
+}
+
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+pub type SpannedResult<T> = std::result::Result<T, SpannedError>;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum Error {
+ Io(String),
+ Message(String),
+ Base64Error(base64::DecodeError),
+ Eof,
+ ExpectedArray,
+ ExpectedArrayEnd,
+ ExpectedAttribute,
+ ExpectedAttributeEnd,
+ ExpectedBoolean,
+ ExpectedComma,
+ ExpectedChar,
+ ExpectedFloat,
+ FloatUnderscore,
+ ExpectedInteger,
+ ExpectedOption,
+ ExpectedOptionEnd,
+ ExpectedMap,
+ ExpectedMapColon,
+ ExpectedMapEnd,
+ ExpectedDifferentStructName {
+ expected: &'static str,
+ found: String,
+ },
+ ExpectedStructLike,
+ ExpectedNamedStructLike(&'static str),
+ ExpectedStructLikeEnd,
+ ExpectedUnit,
+ ExpectedString,
+ ExpectedStringEnd,
+ ExpectedIdentifier,
+
+ InvalidEscape(&'static str),
+
+ IntegerOutOfBounds,
+
+ NoSuchExtension(String),
+
+ UnclosedBlockComment,
+ UnderscoreAtBeginning,
+ UnexpectedByte(char),
+
+ Utf8Error(Utf8Error),
+ TrailingCharacters,
+
+ InvalidValueForType {
+ expected: String,
+ found: String,
+ },
+ ExpectedDifferentLength {
+ expected: String,
+ found: usize,
+ },
+ NoSuchEnumVariant {
+ expected: &'static [&'static str],
+ found: String,
+ outer: Option<String>,
+ },
+ NoSuchStructField {
+ expected: &'static [&'static str],
+ found: String,
+ outer: Option<String>,
+ },
+ MissingStructField {
+ field: &'static str,
+ outer: Option<String>,
+ },
+ DuplicateStructField {
+ field: &'static str,
+ outer: Option<String>,
+ },
+}
+
+impl fmt::Display for SpannedError {
+ 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 Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self {
+ Error::Io(ref s) => f.write_str(s),
+ Error::Message(ref s) => f.write_str(s),
+ Error::Base64Error(ref e) => fmt::Display::fmt(e, f),
+ Error::Eof => f.write_str("Unexpected end of RON"),
+ Error::ExpectedArray => f.write_str("Expected opening `[`"),
+ Error::ExpectedArrayEnd => f.write_str("Expected closing `]`"),
+ Error::ExpectedAttribute => f.write_str("Expected an `#![enable(...)]` attribute"),
+ Error::ExpectedAttributeEnd => {
+ f.write_str("Expected closing `)]` after the enable attribute")
+ }
+ Error::ExpectedBoolean => f.write_str("Expected boolean"),
+ Error::ExpectedComma => f.write_str("Expected comma"),
+ Error::ExpectedChar => f.write_str("Expected char"),
+ Error::ExpectedFloat => f.write_str("Expected float"),
+ Error::FloatUnderscore => f.write_str("Unexpected underscore in float"),
+ Error::ExpectedInteger => f.write_str("Expected integer"),
+ Error::ExpectedOption => f.write_str("Expected option"),
+ Error::ExpectedOptionEnd => f.write_str("Expected closing `)`"),
+ Error::ExpectedMap => f.write_str("Expected opening `{`"),
+ Error::ExpectedMapColon => f.write_str("Expected colon"),
+ Error::ExpectedMapEnd => f.write_str("Expected closing `}`"),
+ Error::ExpectedDifferentStructName {
+ expected,
+ ref found,
+ } => write!(f, "Expected struct `{}` but found `{}`", expected, found),
+ Error::ExpectedStructLike => f.write_str("Expected opening `(`"),
+ Error::ExpectedNamedStructLike(name) => {
+ write!(f, "Expected opening `(` for struct `{}`", name)
+ }
+ Error::ExpectedStructLikeEnd => f.write_str("Expected closing `)`"),
+ Error::ExpectedUnit => f.write_str("Expected unit"),
+ Error::ExpectedString => f.write_str("Expected string"),
+ Error::ExpectedStringEnd => f.write_str("Expected end of string"),
+ Error::ExpectedIdentifier => f.write_str("Expected identifier"),
+ Error::InvalidEscape(s) => f.write_str(s),
+ Error::IntegerOutOfBounds => f.write_str("Integer is out of bounds"),
+ Error::NoSuchExtension(ref name) => write!(f, "No RON extension named `{}`", name),
+ Error::Utf8Error(ref e) => fmt::Display::fmt(e, f),
+ Error::UnclosedBlockComment => f.write_str("Unclosed block comment"),
+ Error::UnderscoreAtBeginning => {
+ f.write_str("Unexpected leading underscore in an integer")
+ }
+ Error::UnexpectedByte(ref byte) => write!(f, "Unexpected byte {:?}", byte),
+ Error::TrailingCharacters => f.write_str("Non-whitespace trailing characters"),
+ Error::InvalidValueForType {
+ ref expected,
+ ref found,
+ } => {
+ write!(f, "Expected {} but found {} instead", expected, found)
+ }
+ Error::ExpectedDifferentLength {
+ ref expected,
+ found,
+ } => {
+ write!(f, "Expected {} but found ", expected)?;
+
+ match found {
+ 0 => f.write_str("zero elements")?,
+ 1 => f.write_str("one element")?,
+ n => write!(f, "{} elements", n)?,
+ }
+
+ f.write_str(" instead")
+ }
+ Error::NoSuchEnumVariant {
+ expected,
+ ref found,
+ ref outer,
+ } => {
+ f.write_str("Unexpected ")?;
+
+ if outer.is_none() {
+ f.write_str("enum ")?;
+ }
+
+ write!(f, "variant named `{}`", found)?;
+
+ if let Some(outer) = outer {
+ write!(f, "in enum `{}`", outer)?;
+ }
+
+ write!(
+ f,
+ ", {}",
+ OneOf {
+ alts: expected,
+ none: "variants"
+ }
+ )
+ }
+ Error::NoSuchStructField {
+ expected,
+ ref found,
+ ref outer,
+ } => {
+ write!(f, "Unexpected field named `{}`", found)?;
+
+ if let Some(outer) = outer {
+ write!(f, "in `{}`", outer)?;
+ }
+
+ write!(
+ f,
+ ", {}",
+ OneOf {
+ alts: expected,
+ none: "fields"
+ }
+ )
+ }
+ Error::MissingStructField { field, ref outer } => {
+ write!(f, "Unexpected missing field `{}`", field)?;
+
+ match outer {
+ Some(outer) => write!(f, " in `{}`", outer),
+ None => Ok(()),
+ }
+ }
+ Error::DuplicateStructField { field, ref outer } => {
+ write!(f, "Unexpected duplicate field `{}`", field)?;
+
+ match outer {
+ Some(outer) => write!(f, " in `{}`", outer),
+ None => Ok(()),
+ }
+ }
+ }
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct Position {
+ pub line: usize,
+ pub col: usize,
+}
+
+impl fmt::Display for Position {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}:{}", self.line, self.col)
+ }
+}
+
+impl ser::Error for Error {
+ #[cold]
+ fn custom<T: fmt::Display>(msg: T) -> Self {
+ Error::Message(msg.to_string())
+ }
+}
+
+impl de::Error for Error {
+ #[cold]
+ fn custom<T: fmt::Display>(msg: T) -> Self {
+ Error::Message(msg.to_string())
+ }
+
+ #[cold]
+ fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
+ // Invalid type and invalid value are merged given their similarity in ron
+ Self::invalid_value(unexp, exp)
+ }
+
+ #[cold]
+ fn invalid_value(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
+ struct UnexpectedSerdeTypeValue<'a>(de::Unexpected<'a>);
+
+ impl<'a> fmt::Display for UnexpectedSerdeTypeValue<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use de::Unexpected::*;
+
+ match self.0 {
+ Bool(b) => write!(f, "the boolean `{}`", b),
+ Unsigned(i) => write!(f, "the unsigned integer `{}`", i),
+ Signed(i) => write!(f, "the signed integer `{}`", i),
+ Float(n) => write!(f, "the floating point number `{}`", n),
+ Char(c) => write!(f, "the UTF-8 character `{}`", c),
+ Str(s) => write!(f, "the string {:?}", s),
+ Bytes(b) => {
+ f.write_str("the bytes b\"")?;
+
+ for b in b {
+ write!(f, "\\x{:02x}", b)?;
+ }
+
+ f.write_str("\"")
+ }
+ Unit => write!(f, "a unit value"),
+ Option => write!(f, "an optional value"),
+ NewtypeStruct => write!(f, "a newtype struct"),
+ Seq => write!(f, "a sequence"),
+ Map => write!(f, "a map"),
+ Enum => write!(f, "an enum"),
+ UnitVariant => write!(f, "a unit variant"),
+ NewtypeVariant => write!(f, "a newtype variant"),
+ TupleVariant => write!(f, "a tuple variant"),
+ StructVariant => write!(f, "a struct variant"),
+ Other(other) => f.write_str(other),
+ }
+ }
+ }
+
+ Error::InvalidValueForType {
+ expected: exp.to_string(),
+ found: UnexpectedSerdeTypeValue(unexp).to_string(),
+ }
+ }
+
+ #[cold]
+ fn invalid_length(len: usize, exp: &dyn de::Expected) -> Self {
+ Error::ExpectedDifferentLength {
+ expected: exp.to_string(),
+ found: len,
+ }
+ }
+
+ #[cold]
+ fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
+ Error::NoSuchEnumVariant {
+ expected,
+ found: variant.to_string(),
+ outer: None,
+ }
+ }
+
+ #[cold]
+ fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
+ Error::NoSuchStructField {
+ expected,
+ found: field.to_string(),
+ outer: None,
+ }
+ }
+
+ #[cold]
+ fn missing_field(field: &'static str) -> Self {
+ Error::MissingStructField { field, outer: None }
+ }
+
+ #[cold]
+ fn duplicate_field(field: &'static str) -> Self {
+ Error::DuplicateStructField { field, outer: None }
+ }
+}
+
+impl StdError for SpannedError {}
+impl StdError for Error {}
+
+impl From<Utf8Error> for Error {
+ fn from(e: Utf8Error) -> Self {
+ Error::Utf8Error(e)
+ }
+}
+
+impl From<FromUtf8Error> for Error {
+ fn from(e: FromUtf8Error) -> Self {
+ Error::Utf8Error(e.utf8_error())
+ }
+}
+
+impl From<io::Error> for Error {
+ fn from(e: io::Error) -> Self {
+ Error::Io(e.to_string())
+ }
+}
+
+impl From<io::Error> for SpannedError {
+ fn from(e: io::Error) -> Self {
+ SpannedError {
+ code: e.into(),
+ position: Position { line: 0, col: 0 },
+ }
+ }
+}
+
+impl From<SpannedError> for Error {
+ fn from(e: SpannedError) -> Self {
+ e.code
+ }
+}
+
+struct OneOf {
+ alts: &'static [&'static str],
+ none: &'static str,
+}
+
+impl fmt::Display for OneOf {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self.alts {
+ [] => write!(f, "there are no {}", self.none),
+ [a1] => write!(f, "expected `{}` instead", a1),
+ [a1, a2] => write!(f, "expected either `{}` or `{}` instead", a1, a2),
+ [a1, ref alts @ ..] => {
+ write!(f, "expected one of `{}`", a1)?;
+
+ for alt in alts {
+ write!(f, ", `{}`", alt)?;
+ }
+
+ f.write_str(" instead")
+ }
+ }
+ }
+}
diff --git a/third_party/rust/ron/src/extensions.rs b/third_party/rust/ron/src/extensions.rs
new file mode 100644
index 0000000000..39357ac7df
--- /dev/null
+++ b/third_party/rust/ron/src/extensions.rs
@@ -0,0 +1,28 @@
+use serde::{Deserialize, Serialize};
+
+bitflags::bitflags! {
+ #[derive(Serialize, Deserialize)]
+ pub struct Extensions: usize {
+ const UNWRAP_NEWTYPES = 0x1;
+ const IMPLICIT_SOME = 0x2;
+ const UNWRAP_VARIANT_NEWTYPES = 0x4;
+ }
+}
+
+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),
+ b"unwrap_variant_newtypes" => Some(Extensions::UNWRAP_VARIANT_NEWTYPES),
+ _ => 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..af7b06bcc5
--- /dev/null
+++ b/third_party/rust/ron/src/lib.rs
@@ -0,0 +1,20 @@
+#![doc = include_str!("../README.md")]
+#![doc(html_root_url = "https://docs.rs/ron/0.8.0")]
+
+pub mod de;
+pub mod ser;
+
+pub mod error;
+pub mod value;
+
+pub mod extensions;
+
+pub mod options;
+
+pub use de::{from_str, Deserializer};
+pub use error::{Error, Result};
+pub use options::Options;
+pub use ser::{to_string, Serializer};
+pub use value::{Map, Number, Value};
+
+mod parse;
diff --git a/third_party/rust/ron/src/options.rs b/third_party/rust/ron/src/options.rs
new file mode 100644
index 0000000000..1e35118122
--- /dev/null
+++ b/third_party/rust/ron/src/options.rs
@@ -0,0 +1,183 @@
+//! Roundtrip serde Options module.
+
+use std::io;
+
+use serde::{de, ser, Deserialize, Serialize};
+
+use crate::de::Deserializer;
+use crate::error::{Result, SpannedResult};
+use crate::extensions::Extensions;
+use crate::ser::{PrettyConfig, Serializer};
+
+/// Roundtrip serde options.
+///
+/// # Examples
+///
+/// ```
+/// use ron::{Options, extensions::Extensions};
+///
+/// let ron = Options::default()
+/// .with_default_extension(Extensions::IMPLICIT_SOME);
+///
+/// let de: Option<i32> = ron.from_str("42").unwrap();
+/// let ser = ron.to_string(&de).unwrap();
+///
+/// assert_eq!(ser, "42");
+/// ```
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(default)]
+#[non_exhaustive]
+pub struct Options {
+ /// Extensions that are enabled by default during serialization and
+ /// deserialization.
+ /// During serialization, these extensions do NOT have to be explicitly
+ /// enabled in the parsed RON.
+ /// During deserialization, these extensions are used, but their explicit
+ /// activation is NOT included in the output RON.
+ /// No extensions are enabled by default.
+ pub default_extensions: Extensions,
+}
+
+impl Default for Options {
+ fn default() -> Self {
+ Self {
+ default_extensions: Extensions::empty(),
+ }
+ }
+}
+
+impl Options {
+ #[must_use]
+ /// Enable `default_extension` by default during serialization and deserialization.
+ pub fn with_default_extension(mut self, default_extension: Extensions) -> Self {
+ self.default_extensions |= default_extension;
+ self
+ }
+
+ #[must_use]
+ /// Do NOT enable `default_extension` by default during serialization and deserialization.
+ pub fn without_default_extension(mut self, default_extension: Extensions) -> Self {
+ self.default_extensions &= !default_extension;
+ self
+ }
+}
+
+impl Options {
+ /// A convenience function for building a deserializer
+ /// and deserializing a value of type `T` from a reader.
+ pub fn from_reader<R, T>(&self, mut rdr: R) -> SpannedResult<T>
+ where
+ R: io::Read,
+ T: de::DeserializeOwned,
+ {
+ let mut bytes = Vec::new();
+ rdr.read_to_end(&mut bytes)?;
+
+ self.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>(&self, s: &'a str) -> SpannedResult<T>
+ where
+ T: de::Deserialize<'a>,
+ {
+ self.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>(&self, s: &'a [u8]) -> SpannedResult<T>
+ where
+ T: de::Deserialize<'a>,
+ {
+ self.from_bytes_seed(s, std::marker::PhantomData)
+ }
+
+ /// A convenience function for building a deserializer
+ /// and deserializing a value of type `T` from a reader
+ /// and a seed.
+ pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T>
+ where
+ R: io::Read,
+ S: for<'a> de::DeserializeSeed<'a, Value = T>,
+ {
+ let mut bytes = Vec::new();
+ rdr.read_to_end(&mut bytes)?;
+
+ self.from_bytes_seed(&bytes, seed)
+ }
+
+ /// A convenience function for building a deserializer
+ /// and deserializing a value of type `T` from a string
+ /// and a seed.
+ pub fn from_str_seed<'a, S, T>(&self, s: &'a str, seed: S) -> SpannedResult<T>
+ where
+ S: de::DeserializeSeed<'a, Value = T>,
+ {
+ self.from_bytes_seed(s.as_bytes(), seed)
+ }
+
+ /// A convenience function for building a deserializer
+ /// and deserializing a value of type `T` from bytes
+ /// and a seed.
+ pub fn from_bytes_seed<'a, S, T>(&self, s: &'a [u8], seed: S) -> SpannedResult<T>
+ where
+ S: de::DeserializeSeed<'a, Value = T>,
+ {
+ let mut deserializer = Deserializer::from_bytes_with_options(s, self.clone())?;
+
+ let value = seed
+ .deserialize(&mut deserializer)
+ .map_err(|e| deserializer.span_error(e))?;
+
+ deserializer.end().map_err(|e| deserializer.span_error(e))?;
+
+ Ok(value)
+ }
+
+ /// Serializes `value` into `writer`
+ pub fn to_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
+ where
+ W: io::Write,
+ T: ?Sized + ser::Serialize,
+ {
+ let mut s = Serializer::with_options(writer, None, self.clone())?;
+ value.serialize(&mut s)
+ }
+
+ /// Serializes `value` into `writer` in a pretty way.
+ pub fn to_writer_pretty<W, T>(&self, writer: W, value: &T, config: PrettyConfig) -> Result<()>
+ where
+ W: io::Write,
+ T: ?Sized + ser::Serialize,
+ {
+ let mut s = Serializer::with_options(writer, Some(config), self.clone())?;
+ 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>(&self, value: &T) -> Result<String>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let mut output = Vec::new();
+ let mut s = Serializer::with_options(&mut output, None, self.clone())?;
+ value.serialize(&mut s)?;
+ Ok(String::from_utf8(output).expect("Ron should be utf-8"))
+ }
+
+ /// Serializes `value` in the recommended RON layout in a pretty way.
+ pub fn to_string_pretty<T>(&self, value: &T, config: PrettyConfig) -> Result<String>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let mut output = Vec::new();
+ let mut s = Serializer::with_options(&mut output, Some(config), self.clone())?;
+ value.serialize(&mut s)?;
+ Ok(String::from_utf8(output).expect("Ron should be utf-8"))
+ }
+}
diff --git a/third_party/rust/ron/src/parse.rs b/third_party/rust/ron/src/parse.rs
new file mode 100644
index 0000000000..b0cc632f30
--- /dev/null
+++ b/third_party/rust/ron/src/parse.rs
@@ -0,0 +1,978 @@
+#![allow(clippy::identity_op)]
+
+use std::{
+ char::from_u32 as char_from_u32,
+ str::{from_utf8, from_utf8_unchecked, FromStr},
+};
+
+use crate::{
+ error::{Error, Position, Result, SpannedError, SpannedResult},
+ 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 IDENT_RAW_CHAR: u8 = 1 << 4; // [A-Za-z_0-9\.+-]
+const WHITESPACE_CHAR: u8 = 1 << 5; // [\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 | IDENT_RAW_CHAR; // [0-9]
+const ABCDF: u8 = INT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR | IDENT_RAW_CHAR; // [ABCDFabcdf]
+const UNDER: u8 = INT_CHAR | FLOAT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR | IDENT_RAW_CHAR; // [_]
+const E____: u8 = INT_CHAR | FLOAT_CHAR | IDENT_FIRST_CHAR | IDENT_OTHER_CHAR | IDENT_RAW_CHAR; // [Ee]
+const G2Z__: u8 = IDENT_FIRST_CHAR | IDENT_OTHER_CHAR | IDENT_RAW_CHAR; // [G-Zg-z]
+const PUNCT: u8 = FLOAT_CHAR | IDENT_RAW_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
+}
+
+pub const fn is_ident_first_char(c: u8) -> bool {
+ ENCODINGS[c as usize] & IDENT_FIRST_CHAR != 0
+}
+
+pub const fn is_ident_other_char(c: u8) -> bool {
+ ENCODINGS[c as usize] & IDENT_OTHER_CHAR != 0
+}
+
+const fn is_ident_raw_char(c: u8) -> bool {
+ ENCODINGS[c as usize] & IDENT_RAW_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),
+ #[cfg(feature = "integer128")]
+ I128(i128),
+ #[cfg(feature = "integer128")]
+ U128(u128),
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct Bytes<'a> {
+ /// Bits set according to the `Extensions` enum.
+ pub exts: Extensions,
+ bytes: &'a [u8],
+ cursor: Position,
+}
+
+#[cfg(feature = "integer128")]
+pub(crate) type LargeUInt = u128;
+#[cfg(not(feature = "integer128"))]
+pub(crate) type LargeUInt = u64;
+#[cfg(feature = "integer128")]
+pub(crate) type LargeSInt = i128;
+#[cfg(not(feature = "integer128"))]
+pub(crate) type LargeSInt = i64;
+
+impl<'a> Bytes<'a> {
+ pub fn new(bytes: &'a [u8]) -> SpannedResult<Self> {
+ let mut b = Bytes {
+ exts: Extensions::empty(),
+ bytes,
+ cursor: Position { line: 1, col: 1 },
+ };
+
+ b.skip_ws().map_err(|e| b.span_error(e))?;
+
+ // Loop over all extensions attributes
+ loop {
+ let attribute = b.extensions().map_err(|e| b.span_error(e))?;
+
+ if attribute.is_empty() {
+ break;
+ }
+
+ b.exts |= attribute;
+ b.skip_ws().map_err(|e| b.span_error(e))?;
+ }
+
+ Ok(b)
+ }
+
+ pub fn span_error(&self, code: Error) -> SpannedError {
+ SpannedError {
+ code,
+ position: self.cursor,
+ }
+ }
+
+ 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.cursor.line += 1;
+ self.cursor.col = 1;
+ } else {
+ self.cursor.col += 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 Err(Error::ExpectedInteger);
+ }
+
+ let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) };
+
+ if s.as_bytes()[0] == b'_' {
+ return Err(Error::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 Err(Error::IntegerOutOfBounds);
+ }
+
+ let digit = bytes.decode_hex(byte)?;
+
+ if digit >= base {
+ return Err(Error::ExpectedInteger);
+ }
+
+ if f(&mut num_acc, digit) {
+ return Err(Error::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 == f64::from(f as f32) {
+ 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 = LargeUInt::from(std::u8::MAX);
+ let max_u16 = LargeUInt::from(std::u16::MAX);
+ let max_u32 = LargeUInt::from(std::u32::MAX);
+ #[cfg_attr(not(feature = "integer128"), allow(clippy::useless_conversion))]
+ let max_u64 = LargeUInt::from(std::u64::MAX);
+
+ let min_i8 = LargeSInt::from(std::i8::MIN);
+ let max_i8 = LargeSInt::from(std::i8::MAX);
+ let min_i16 = LargeSInt::from(std::i16::MIN);
+ let max_i16 = LargeSInt::from(std::i16::MAX);
+ let min_i32 = LargeSInt::from(std::i32::MIN);
+ let max_i32 = LargeSInt::from(std::i32::MAX);
+ #[cfg_attr(not(feature = "integer128"), allow(clippy::useless_conversion))]
+ let min_i64 = LargeSInt::from(std::i64::MIN);
+ #[cfg_attr(not(feature = "integer128"), allow(clippy::useless_conversion))]
+ let max_i64 = LargeSInt::from(std::i64::MAX);
+
+ if is_signed {
+ match self.signed_integer::<LargeSInt>() {
+ 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 {
+ #[cfg(feature = "integer128")]
+ {
+ Ok(AnyNum::I128(x))
+ }
+ #[cfg(not(feature = "integer128"))]
+ {
+ Ok(AnyNum::I64(x))
+ }
+ }
+ }
+ Err(_) => {
+ self.bytes = bytes_backup;
+
+ any_float(self.float::<f64>()?)
+ }
+ }
+ } else {
+ match self.unsigned_integer::<LargeUInt>() {
+ 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 {
+ #[cfg(feature = "integer128")]
+ {
+ Ok(AnyNum::U128(x))
+ }
+ #[cfg(not(feature = "integer128"))]
+ {
+ Ok(AnyNum::U64(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 {
+ Err(Error::ExpectedBoolean)
+ }
+ }
+
+ pub fn bytes(&self) -> &[u8] {
+ self.bytes
+ }
+
+ pub fn char(&mut self) -> Result<char> {
+ if !self.consume("'") {
+ return Err(Error::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(Error::ExpectedChar)?;
+ let s = from_utf8(&self.bytes[0..pos]).map_err(Error::from)?;
+ let mut chars = s.chars();
+
+ let first = chars.next().ok_or(Error::ExpectedChar)?;
+ if chars.next().is_some() {
+ return Err(Error::ExpectedChar);
+ }
+
+ let _ = self.advance(pos);
+
+ first
+ };
+
+ if !self.consume("'") {
+ return Err(Error::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_struct_name(&mut self, ident: &'static str) -> Result<bool> {
+ if self.check_ident("") {
+ Ok(false)
+ } else if ident.is_empty() {
+ Err(Error::ExpectedStructLike)
+ } else if self.check_ident(ident) {
+ let _ = self.advance(ident.len());
+
+ Ok(true)
+ } else {
+ // If the following is not even an identifier, then a missing
+ // opening `(` seems more likely
+ let maybe_ident = self
+ .identifier()
+ .map_err(|_| Error::ExpectedNamedStructLike(ident))?;
+
+ let found = std::str::from_utf8(maybe_ident).map_err(Error::from)?;
+
+ Err(Error::ExpectedDifferentStructName {
+ expected: ident,
+ found: String::from(found),
+ })
+ }
+ }
+
+ 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 expect_byte(&mut self, byte: u8, error: Error) -> Result<()> {
+ self.eat_byte()
+ .and_then(|b| if b == byte { Ok(()) } else { 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 Err(Error::ExpectedAttribute);
+ }
+
+ self.skip_ws()?;
+ let mut extensions = Extensions::empty();
+
+ loop {
+ let ident = self.identifier()?;
+ let extension = Extensions::from_ident(ident).ok_or_else(|| {
+ Error::NoSuchExtension(String::from_utf8_lossy(ident).into_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 Err(Error::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(Error::ExpectedAttributeEnd)
+ }
+ }
+
+ pub fn float<T>(&mut self) -> Result<T>
+ where
+ T: FromStr,
+ {
+ for literal in &["inf", "+inf", "-inf", "NaN", "+NaN", "-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);
+
+ // Since `rustc` allows `1_0.0_1`, lint against underscores in floats
+ if let Some(err_bytes) = self.bytes[0..num_bytes].iter().position(|b| *b == b'_') {
+ let _ = self.advance(err_bytes);
+
+ return Err(Error::FloatUnderscore);
+ }
+
+ let s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) };
+ let res = FromStr::from_str(s).map_err(|_| Error::ExpectedFloat);
+
+ let _ = self.advance(num_bytes);
+
+ res
+ }
+
+ pub fn identifier(&mut self) -> Result<&'a [u8]> {
+ let next = self.peek_or_eof()?;
+ if !is_ident_first_char(next) {
+ return Err(Error::ExpectedIdentifier);
+ }
+
+ // If the next two bytes signify the start of a raw string literal,
+ // return an error.
+ let length = if next == b'r' {
+ match self.bytes.get(1).ok_or(Error::Eof)? {
+ b'"' => return Err(Error::ExpectedIdentifier),
+ b'#' => {
+ let after_next = self.bytes.get(2).cloned().unwrap_or_default();
+ // Note: it's important to check this before advancing forward, so that
+ // the value-type deserializer can fall back to parsing it differently.
+ if !is_ident_raw_char(after_next) {
+ return Err(Error::ExpectedIdentifier);
+ }
+ // skip "r#"
+ let _ = self.advance(2);
+ self.next_bytes_contained_in(is_ident_raw_char)
+ }
+ _ => self.next_bytes_contained_in(is_ident_other_char),
+ }
+ } else {
+ self.next_bytes_contained_in(is_ident_other_char)
+ };
+
+ let ident = &self.bytes[..length];
+ let _ = self.advance(length);
+
+ Ok(ident)
+ }
+
+ 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<()> {
+ loop {
+ while self.peek().map_or(false, is_whitespace_char) {
+ let _ = self.advance_single();
+ }
+
+ if !self.skip_comment()? {
+ return Ok(());
+ }
+ }
+ }
+
+ pub fn peek(&self) -> Option<u8> {
+ self.bytes.first().cloned()
+ }
+
+ pub fn peek_or_eof(&self) -> Result<u8> {
+ self.bytes.first().cloned().ok_or(Error::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 {
+ Err(Error::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(Error::ExpectedStringEnd)?;
+
+ if *end_or_escape == b'"' {
+ let s = from_utf8(&self.bytes[..i]).map_err(Error::from)?;
+
+ // 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(Error::ExpectedStringEnd)?;
+
+ 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(Error::from)?;
+ 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 Err(Error::ExpectedString);
+ }
+
+ let ending = [&[b'"'], hashes].concat();
+ let i = self
+ .bytes
+ .windows(num_hashes + 1)
+ .position(|window| window == ending.as_slice())
+ .ok_or(Error::ExpectedStringEnd)?;
+
+ let s = from_utf8(&self.bytes[..i]).map_err(Error::from)?;
+
+ // 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'),
+ _ => Err(Error::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'0' => '\0',
+ b'x' => self.decode_ascii_escape()? as char,
+ b'u' => {
+ self.expect_byte(b'{', Error::InvalidEscape("Missing { in Unicode escape"))?;
+
+ 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 |= u32::from(byte);
+
+ num_digits += 1;
+ }
+
+ if num_digits == 0 {
+ return Err(Error::InvalidEscape(
+ "Expected 1-6 digits, got 0 digits in Unicode escape",
+ ));
+ }
+
+ self.expect_byte(
+ b'}',
+ Error::InvalidEscape("No } at the end of Unicode escape"),
+ )?;
+ char_from_u32(bytes).ok_or(Error::InvalidEscape("Not a valid char"))?
+ }
+ _ => {
+ return Err(Error::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 Err(Error::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(|_| Error::UnclosedBlockComment)?;
+ }
+ }
+ }
+ b => return Err(Error::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); )*
+ };
+}
+
+#[cfg(feature = "integer128")]
+impl_num!(u8 u16 u32 u64 u128 i8 i16 i32 i64 i128);
+#[cfg(not(feature = "integer128"))]
+impl_num!(u8 u16 u32 u64 i8 i16 i32 i64);
+
+#[derive(Clone, Debug)]
+pub enum ParsedStr<'a> {
+ Allocated(String),
+ Slice(&'a str),
+}
+
+#[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..f723d15e09
--- /dev/null
+++ b/third_party/rust/ron/src/ser/mod.rs
@@ -0,0 +1,996 @@
+use serde::{ser, Deserialize, Serialize};
+use std::io;
+
+use crate::{
+ error::{Error, Result},
+ extensions::Extensions,
+ options::Options,
+ parse::{is_ident_first_char, is_ident_other_char, LargeSInt, LargeUInt},
+};
+
+#[cfg(test)]
+mod tests;
+mod value;
+
+/// Serializes `value` into `writer`
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ?Sized + Serialize,
+{
+ Options::default().to_writer(writer, value)
+}
+
+/// 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: ?Sized + Serialize,
+{
+ Options::default().to_writer_pretty(writer, value, config)
+}
+
+/// 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: ?Sized + Serialize,
+{
+ Options::default().to_string(value)
+}
+
+/// 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: ?Sized + Serialize,
+{
+ Options::default().to_string_pretty(value, config)
+}
+
+/// Pretty serializer state
+struct Pretty {
+ indent: usize,
+ sequence_index: Vec<usize>,
+}
+
+/// Pretty serializer configuration.
+///
+/// # Examples
+///
+/// ```
+/// use ron::ser::PrettyConfig;
+///
+/// let my_config = PrettyConfig::new()
+/// .depth_limit(4)
+/// // definitely superior (okay, just joking)
+/// .indentor("\t".to_owned());
+/// ```
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(default)]
+#[non_exhaustive]
+pub struct PrettyConfig {
+ /// Limit the pretty-ness up to the given depth.
+ pub depth_limit: usize,
+ /// New line string
+ pub new_line: String,
+ /// Indentation string
+ pub indentor: String,
+ /// Separator string
+ pub separator: String,
+ // Whether to emit struct names
+ pub struct_names: bool,
+ /// Separate tuple members with indentation
+ pub separate_tuple_members: bool,
+ /// Enumerate array items in comments
+ pub enumerate_arrays: bool,
+ /// Enable extensions. Only configures 'implicit_some',
+ /// 'unwrap_newtypes', and 'unwrap_variant_newtypes' for now.
+ pub extensions: Extensions,
+ /// Enable compact arrays
+ pub compact_arrays: bool,
+}
+
+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 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 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 indentor(mut self, indentor: String) -> Self {
+ self.indentor = indentor;
+
+ self
+ }
+
+ /// Configures the string sequence used to separate items inline.
+ ///
+ /// Default: 1 space
+ pub fn separator(mut self, separator: String) -> Self {
+ self.separator = separator;
+
+ self
+ }
+
+ /// Configures whether to emit struct names.
+ ///
+ /// Default: `false`
+ pub fn struct_names(mut self, struct_names: bool) -> Self {
+ self.struct_names = struct_names;
+
+ 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 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 enumerate_arrays(mut self, enumerate_arrays: bool) -> Self {
+ self.enumerate_arrays = enumerate_arrays;
+
+ self
+ }
+
+ /// Configures whether every array should be a single line (true) or a multi line one (false)
+ /// When false, `["a","b"]` (as well as any array) will serialize to
+ /// `
+ /// [
+ /// "a",
+ /// "b",
+ /// ]
+ /// `
+ /// When true, `["a","b"]` (as well as any array) will serialize to `["a","b"]`
+ ///
+ /// Default: `false`
+ pub fn compact_arrays(mut self, compact_arrays: bool) -> Self {
+ self.compact_arrays = compact_arrays;
+
+ self
+ }
+
+ /// Configures extensions
+ ///
+ /// Default: Extensions::empty()
+ pub fn extensions(mut self, extensions: Extensions) -> Self {
+ self.extensions = extensions;
+
+ self
+ }
+}
+
+impl Default for PrettyConfig {
+ fn default() -> Self {
+ PrettyConfig {
+ depth_limit: !0,
+ new_line: if cfg!(not(target_os = "windows")) {
+ String::from("\n")
+ } else {
+ String::from("\r\n")
+ },
+ indentor: String::from(" "),
+ separator: String::from(" "),
+ struct_names: false,
+ separate_tuple_members: false,
+ enumerate_arrays: false,
+ extensions: Extensions::empty(),
+ compact_arrays: false,
+ }
+ }
+}
+
+/// 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)>,
+ default_extensions: Extensions,
+ is_empty: Option<bool>,
+ newtype_variant: 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(writer: W, config: Option<PrettyConfig>) -> Result<Self> {
+ Self::with_options(writer, config, Options::default())
+ }
+
+ /// Creates a new `Serializer`.
+ ///
+ /// Most of the time you can just use `to_string` or `to_string_pretty`.
+ pub fn with_options(
+ mut writer: W,
+ config: Option<PrettyConfig>,
+ options: Options,
+ ) -> Result<Self> {
+ if let Some(conf) = &config {
+ let non_default_extensions = !options.default_extensions;
+
+ if (non_default_extensions & conf.extensions).contains(Extensions::IMPLICIT_SOME) {
+ writer.write_all(b"#![enable(implicit_some)]")?;
+ writer.write_all(conf.new_line.as_bytes())?;
+ };
+ if (non_default_extensions & conf.extensions).contains(Extensions::UNWRAP_NEWTYPES) {
+ writer.write_all(b"#![enable(unwrap_newtypes)]")?;
+ writer.write_all(conf.new_line.as_bytes())?;
+ };
+ if (non_default_extensions & conf.extensions)
+ .contains(Extensions::UNWRAP_VARIANT_NEWTYPES)
+ {
+ writer.write_all(b"#![enable(unwrap_variant_newtypes)]")?;
+ writer.write_all(conf.new_line.as_bytes())?;
+ };
+ };
+ Ok(Serializer {
+ output: writer,
+ pretty: config.map(|conf| {
+ (
+ conf,
+ Pretty {
+ indent: 0,
+ sequence_index: Vec::new(),
+ },
+ )
+ }),
+ default_extensions: options.default_extensions,
+ is_empty: None,
+ newtype_variant: false,
+ })
+ }
+
+ fn separate_tuple_members(&self) -> bool {
+ self.pretty
+ .as_ref()
+ .map_or(false, |&(ref config, _)| config.separate_tuple_members)
+ }
+
+ fn compact_arrays(&self) -> bool {
+ self.pretty
+ .as_ref()
+ .map_or(false, |&(ref config, _)| config.compact_arrays)
+ }
+
+ fn extensions(&self) -> Extensions {
+ self.default_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(())
+ }
+
+ fn serialize_sint(&mut self, value: impl Into<LargeSInt>) -> Result<()> {
+ // TODO optimize
+ write!(self.output, "{}", value.into())?;
+
+ Ok(())
+ }
+
+ fn serialize_uint(&mut self, value: impl Into<LargeUInt>) -> Result<()> {
+ // TODO optimize
+ write!(self.output, "{}", value.into())?;
+
+ Ok(())
+ }
+
+ fn write_identifier(&mut self, name: &str) -> io::Result<()> {
+ let mut bytes = name.as_bytes().iter().cloned();
+ if !bytes.next().map_or(false, is_ident_first_char) || !bytes.all(is_ident_other_char) {
+ self.output.write_all(b"r#")?;
+ }
+ self.output.write_all(name.as_bytes())?;
+ Ok(())
+ }
+
+ fn struct_names(&self) -> bool {
+ self.pretty
+ .as_ref()
+ .map(|(pc, _)| pc.struct_names)
+ .unwrap_or(false)
+ }
+}
+
+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_sint(v)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<()> {
+ self.serialize_sint(v)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<()> {
+ self.serialize_sint(v)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<()> {
+ self.serialize_sint(v)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn serialize_i128(self, v: i128) -> Result<()> {
+ self.serialize_sint(v)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<()> {
+ self.serialize_uint(v)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<()> {
+ self.serialize_uint(v)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<()> {
+ self.serialize_uint(v)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<()> {
+ self.serialize_uint(v)
+ }
+
+ #[cfg(feature = "integer128")]
+ fn serialize_u128(self, v: u128) -> Result<()> {
+ self.serialize_uint(v)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<()> {
+ write!(self.output, "{}", v)?;
+ if v.fract() == 0.0 {
+ write!(self.output, ".0")?;
+ }
+ Ok(())
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<()> {
+ write!(self.output, "{}", v)?;
+ if v.fract() == 0.0 {
+ 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<()> {
+ if !self.newtype_variant {
+ self.output.write_all(b"()")?;
+ }
+
+ self.newtype_variant = false;
+
+ Ok(())
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
+ if self.struct_names() && !self.newtype_variant {
+ self.write_identifier(name)?;
+
+ Ok(())
+ } else {
+ self.serialize_unit()
+ }
+ }
+
+ fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
+ self.write_identifier(variant)?;
+
+ Ok(())
+ }
+
+ fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ if self.extensions().contains(Extensions::UNWRAP_NEWTYPES) || self.newtype_variant {
+ self.newtype_variant = false;
+
+ return value.serialize(&mut *self);
+ }
+
+ if self.struct_names() {
+ self.write_identifier(name)?;
+ }
+
+ 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.write_identifier(variant)?;
+ self.output.write_all(b"(")?;
+
+ self.newtype_variant = self
+ .extensions()
+ .contains(Extensions::UNWRAP_VARIANT_NEWTYPES);
+
+ value.serialize(&mut *self)?;
+
+ self.newtype_variant = false;
+
+ self.output.write_all(b")")?;
+ Ok(())
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
+ self.newtype_variant = false;
+
+ self.output.write_all(b"[")?;
+
+ if let Some(len) = len {
+ self.is_empty = Some(len == 0);
+ }
+
+ if !self.compact_arrays() {
+ self.start_indent()?;
+ }
+
+ if let Some((_, ref mut pretty)) = self.pretty {
+ pretty.sequence_index.push(0);
+ }
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: false,
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ let old_newtype_variant = self.newtype_variant;
+ self.newtype_variant = false;
+
+ if !old_newtype_variant {
+ self.output.write_all(b"(")?;
+ }
+
+ if self.separate_tuple_members() {
+ self.is_empty = Some(len == 0);
+
+ self.start_indent()?;
+ }
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: old_newtype_variant,
+ })
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ if self.struct_names() && !self.newtype_variant {
+ self.write_identifier(name)?;
+ }
+
+ self.serialize_tuple(len)
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ self.newtype_variant = false;
+
+ self.write_identifier(variant)?;
+ self.output.write_all(b"(")?;
+
+ if self.separate_tuple_members() {
+ self.is_empty = Some(len == 0);
+
+ self.start_indent()?;
+ }
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: false,
+ })
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
+ self.newtype_variant = false;
+
+ self.output.write_all(b"{")?;
+
+ if let Some(len) = len {
+ self.is_empty = Some(len == 0);
+ }
+
+ self.start_indent()?;
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: false,
+ })
+ }
+
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ let old_newtype_variant = self.newtype_variant;
+ self.newtype_variant = false;
+
+ if !old_newtype_variant {
+ if self.struct_names() {
+ self.write_identifier(name)?;
+ }
+ self.output.write_all(b"(")?;
+ }
+
+ self.is_empty = Some(len == 0);
+ self.start_indent()?;
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: old_newtype_variant,
+ })
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ self.newtype_variant = false;
+
+ self.write_identifier(variant)?;
+ self.output.write_all(b"(")?;
+
+ self.is_empty = Some(len == 0);
+ self.start_indent()?;
+
+ Ok(Compound {
+ ser: self,
+ state: State::First,
+ newtype_variant: false,
+ })
+ }
+}
+
+enum State {
+ First,
+ Rest,
+}
+
+#[doc(hidden)]
+pub struct Compound<'a, W: io::Write> {
+ ser: &'a mut Serializer<W>,
+ state: State,
+ newtype_variant: bool,
+}
+
+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,
+ {
+ if let State::First = self.state {
+ self.state = State::Rest;
+ } else {
+ self.ser.output.write_all(b",")?;
+ if let Some((ref config, ref mut pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit && !config.compact_arrays {
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ } else {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+ }
+ }
+
+ if !self.ser.compact_arrays() {
+ self.ser.indent()?;
+ }
+
+ if let Some((ref mut config, ref mut pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit && config.enumerate_arrays {
+ let index = pretty.sequence_index.last_mut().unwrap();
+ write!(self.ser.output, "/*[{}]*/ ", index)?;
+ *index += 1;
+ }
+ }
+
+ value.serialize(&mut *self.ser)?;
+
+ Ok(())
+ }
+
+ fn end(self) -> Result<()> {
+ if let State::Rest = self.state {
+ if let Some((ref config, ref mut pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit && !config.compact_arrays {
+ self.ser.output.write_all(b",")?;
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ }
+ }
+ }
+
+ if !self.ser.compact_arrays() {
+ self.ser.end_indent()?;
+ }
+
+ if let Some((_, ref mut pretty)) = self.ser.pretty {
+ pretty.sequence_index.pop();
+ }
+
+ // seq always disables `self.newtype_variant`
+ self.ser.output.write_all(b"]")?;
+ Ok(())
+ }
+}
+
+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,
+ {
+ if let State::First = self.state {
+ self.state = State::Rest;
+ } else {
+ self.ser.output.write_all(b",")?;
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit && self.ser.separate_tuple_members() {
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ } else {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+ }
+ }
+
+ if self.ser.separate_tuple_members() {
+ self.ser.indent()?;
+ }
+
+ value.serialize(&mut *self.ser)?;
+
+ Ok(())
+ }
+
+ fn end(self) -> Result<()> {
+ if let State::Rest = self.state {
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if self.ser.separate_tuple_members() && pretty.indent <= config.depth_limit {
+ self.ser.output.write_all(b",")?;
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ }
+ }
+ }
+ if self.ser.separate_tuple_members() {
+ self.ser.end_indent()?;
+ }
+
+ if !self.newtype_variant {
+ self.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,
+ {
+ if let State::First = self.state {
+ self.state = State::Rest;
+ } else {
+ self.ser.output.write_all(b",")?;
+
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit {
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ } else {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+ }
+ }
+ self.ser.indent()?;
+ key.serialize(&mut *self.ser)
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.ser.output.write_all(b":")?;
+
+ if let Some((ref config, _)) = self.ser.pretty {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+
+ value.serialize(&mut *self.ser)?;
+
+ Ok(())
+ }
+
+ fn end(self) -> Result<()> {
+ if let State::Rest = self.state {
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit {
+ self.ser.output.write_all(b",")?;
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ }
+ }
+ }
+ self.ser.end_indent()?;
+ // map always disables `self.newtype_variant`
+ self.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,
+ {
+ if let State::First = self.state {
+ self.state = State::Rest;
+ } else {
+ self.ser.output.write_all(b",")?;
+
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit {
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ } else {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+ }
+ }
+ self.ser.indent()?;
+ self.ser.write_identifier(key)?;
+ self.ser.output.write_all(b":")?;
+
+ if let Some((ref config, _)) = self.ser.pretty {
+ self.ser.output.write_all(config.separator.as_bytes())?;
+ }
+
+ value.serialize(&mut *self.ser)?;
+
+ Ok(())
+ }
+
+ fn end(self) -> Result<()> {
+ if let State::Rest = self.state {
+ if let Some((ref config, ref pretty)) = self.ser.pretty {
+ if pretty.indent <= config.depth_limit {
+ self.ser.output.write_all(b",")?;
+ self.ser.output.write_all(config.new_line.as_bytes())?;
+ }
+ }
+ }
+ self.ser.end_indent()?;
+ if !self.newtype_variant {
+ self.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)
+ }
+}
diff --git a/third_party/rust/ron/src/ser/tests.rs b/third_party/rust/ron/src/ser/tests.rs
new file mode 100644
index 0000000000..f1056e6575
--- /dev/null
+++ b/third_party/rust/ron/src/ser/tests.rs
@@ -0,0 +1,146 @@
+use super::to_string;
+use serde::Serialize;
+
+#[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.0,y:7.0)");
+
+ #[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.0,5.0)");
+}
+
+#[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_slice() {
+ assert_eq!(to_string(&[0, 1, 2, 3, 4, 5][..]).unwrap(), "[0,1,2,3,4,5]");
+ assert_eq!(to_string(&[0, 1, 2, 3, 4, 5][1..4]).unwrap(), "[1,2,3]");
+}
+
+#[test]
+fn test_vec() {
+ assert_eq!(to_string(&vec![0, 1, 2, 3, 4, 5]).unwrap(), "[0,1,2,3,4,5]");
+}
+
+#[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==\""
+ )
+ );
+}
+
+#[test]
+fn rename() {
+ #[derive(Serialize, Debug, PartialEq)]
+ enum Foo {
+ #[serde(rename = "2d")]
+ D2,
+ #[serde(rename = "triangle-list")]
+ TriangleList,
+ }
+
+ assert_eq!(to_string(&Foo::D2).unwrap(), "r#2d");
+ assert_eq!(to_string(&Foo::TriangleList).unwrap(), "r#triangle-list");
+}
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..565bfa05e3
--- /dev/null
+++ b/third_party/rust/ron/src/value.rs
@@ -0,0 +1,553 @@
+//! Value module.
+
+use std::{
+ cmp::{Eq, Ordering},
+ hash::{Hash, Hasher},
+ iter::FromIterator,
+ ops::{Index, IndexMut},
+};
+
+use serde::{
+ de::{DeserializeOwned, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor},
+ forward_to_deserialize_any, Deserialize, Serialize,
+};
+
+use crate::de::Error;
+use crate::error::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)]
+#[serde(transparent)]
+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) -> bool {
+ self.0.len() == 0
+ }
+
+ /// 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(i64::from(i))
+ }
+}
+
+// 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 <= std::i64::MAX as u64 {
+ 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.to_bits());
+ }
+}
+
+/// 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 = Error;
+
+ 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(Error::Message(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(Error::Message(format!("Expected a number, got {:?}", v))),
+ }
+ }
+}
+
+struct MapAccessor {
+ keys: Vec<Value>,
+ values: Vec<Value>,
+}
+
+impl<'de> MapAccess<'de> for MapAccessor {
+ type Error = Error;
+
+ 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 = Error;
+
+ 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::<()>("()");
+ }
+}