diff --git a/src/de.rs b/src/de.rs index ffd0d48c2..e263f333a 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,28 +1,39 @@ //! Deserialize JSON data to a Rust data structure. -use crate::error::{Error, ErrorCode, Result}; -#[cfg(feature = "float_roundtrip")] -use crate::lexical; -use crate::number::Number; -use crate::read::{self, Fused, Reference}; -use alloc::string::String; -use alloc::vec::Vec; +use alloc::{string::String, vec::Vec}; #[cfg(feature = "float_roundtrip")] use core::iter; -use core::iter::FusedIterator; -use core::marker::PhantomData; -use core::result; -use core::str::FromStr; -use serde::de::{self, Expected, Unexpected}; -use serde::{forward_to_deserialize_any, serde_if_integer128}; +use core::{iter::FusedIterator, marker::PhantomData, result, str::FromStr}; +use serde::{ + de::{self, Expected, Unexpected}, + forward_to_deserialize_any, serde_if_integer128, +}; + +#[cfg(feature = "float_roundtrip")] +use crate::lexical; #[cfg(feature = "arbitrary_precision")] use crate::number::NumberDeserializer; - -pub use crate::read::{Read, SliceRead, StrRead}; - #[cfg(feature = "std")] pub use crate::read::IoRead; +pub use crate::read::{Read, SliceRead, StrRead}; +use crate::{ + error::{Error, ErrorCode, Result}, + number::Number, + read::{self, Fused, Reference}, +}; + +macro_rules! try_with { + ($e:expr, $wrap:expr) => { + match $e { + core::result::Result::Ok(val) => val, + core::result::Result::Err(err) => return $wrap(err), + } + }; + ($e:expr, $wrap:expr,) => { + try_with!($e, $wrap) + }; +} ////////////////////////////////////////////////////////////////////////////// @@ -132,6 +143,63 @@ impl ParserNumber { } } +/// Flattened `Result`. Helps llvm when optimizing +enum StructResult<'a, R> { + Array(SeqAccess<'a, R>), + Map(MapAccess<'a, R>), + Error(Error), +} + +enum EnumResult<'a, R> { + Variant(VariantAccess<'a, R>), + Unit(UnitVariantAccess<'a, R>), + Error(Error), +} + +enum OptionResult { + Some, + None, + Error(Error), +} + +#[cfg(not(feature = "unbounded_depth"))] +macro_rules! if_checking_recursion_limit { + ($($body:tt)*) => { + $($body)* + }; +} + +#[cfg(feature = "unbounded_depth")] +macro_rules! if_checking_recursion_limit { + ($this:ident $($body:tt)*) => { + if !$this.disable_recursion_limit { + $this $($body)* + } + }; +} + +macro_rules! check_recursion_prefix { + ($self_: ident, $error: path) => { + if_checking_recursion_limit! { + $self_.remaining_depth -= 1; + if $self_.remaining_depth == 0 { + return $error($self_.error(ErrorCode::RecursionLimitExceeded)); + } + } + }; +} + +enum AnyResult<'de, 's> { + Null, + Bool(bool), + Number(bool), + BorrowedString(&'de str), + CopiedString(&'s str), + Array, + Map, + Error(Error), +} + impl<'de, R: Read<'de>> Deserializer { /// The `Deserializer::end` method should be called after a value has been fully deserialized. /// This allows the `Deserializer` to validate that the input stream is at the end or that it @@ -229,6 +297,13 @@ impl<'de, R: Read<'de>> Deserializer { Ok(tri!(self.next_char()).unwrap_or(b'\x00')) } + fn next_char_or_error(&mut self) -> Result { + match tri!(self.read.next()) { + Some(next) => Ok(next), + None => Err(self.error(ErrorCode::EofWhileParsingValue)), + } + } + /// Error caused by a byte from next_char(). #[cold] fn error(&self, reason: ErrorCode) -> Error { @@ -243,6 +318,179 @@ impl<'de, R: Read<'de>> Deserializer { Error::syntax(reason, position.line, position.column) } + fn parse_any_prefix(&mut self) -> AnyResult<'de, '_> { + match try_with!(self.parse_whitespace_in_value(), AnyResult::Error) { + b'n' => { + self.eat_char(); + try_with!(self.parse_ident(b"ull"), AnyResult::Error); + AnyResult::Null + } + b't' => { + self.eat_char(); + try_with!(self.parse_ident(b"rue"), AnyResult::Error); + AnyResult::Bool(true) + } + b'f' => { + self.eat_char(); + try_with!(self.parse_ident(b"alse"), AnyResult::Error); + AnyResult::Bool(false) + } + b'-' => { + self.eat_char(); + AnyResult::Number(false) + } + b'0'..=b'9' => AnyResult::Number(true), + b'"' => match try_with!(self.parse_str(), AnyResult::Error) { + Reference::Borrowed(s) => AnyResult::BorrowedString(s), + Reference::Copied(s) => AnyResult::CopiedString(s), + }, + b'[' => { + self.eat_char(); + check_recursion_prefix!(self, AnyResult::Error); + AnyResult::Array + } + b'{' => { + self.eat_char(); + check_recursion_prefix!(self, AnyResult::Error); + AnyResult::Map + } + _ => AnyResult::Error(self.peek_error(ErrorCode::ExpectedSomeValue)), + } + } + + fn parse_number_prefix(&mut self, exp: &dyn Expected) -> Result { + let peek = tri!(self.parse_whitespace_in_value()); + + match peek { + b'-' => { + self.eat_char(); + self.parse_integer(false) + } + b'0'..=b'9' => self.parse_integer(true), + _ => Err(self.peek_invalid_type(exp)), + } + } + + fn parse_str<'s>(&'s mut self) -> Result> { + self.eat_char(); + self.scratch.clear(); + self.read.parse_str(&mut self.scratch) + } + + fn parse_str_raw<'s>(&'s mut self) -> Result> { + self.eat_char(); + self.scratch.clear(); + self.read.parse_str_raw(&mut self.scratch) + } + + fn parse_str_prefix<'s>(&'s mut self, exp: &dyn Expected) -> Result> { + tri!(self.parse_whitespace_until(b'"', exp)); + + self.scratch.clear(); + self.read.parse_str(&mut self.scratch) + } + + fn parse_seq_prefix(&mut self, exp: &dyn Expected) -> Result<()> { + tri!(self.parse_whitespace_until(b'[', exp)); + check_recursion_prefix!(self, Err); + Ok(()) + } + + fn parse_map_prefix(&mut self, exp: &dyn Expected) -> Result<()> { + tri!(self.parse_whitespace_until(b'{', exp)); + check_recursion_prefix!(self, Err); + Ok(()) + } + + fn parse_struct_prefix(&mut self, exp: &dyn Expected) -> StructResult<'_, R> { + match self.parse_whitespace_in_value() { + Ok(b'[') => { + self.eat_char(); + check_recursion_prefix!(self, StructResult::Error); + StructResult::Array(SeqAccess::new(self)) + } + Ok(b'{') => { + self.eat_char(); + check_recursion_prefix!(self, StructResult::Error); + StructResult::Map(MapAccess::new(self)) + } + Ok(_) => { + let err = self.peek_invalid_type(exp); + StructResult::Error(self.fix_position(err)) + } + Err(err) => StructResult::Error(err), + } + } + + fn parse_enum_prefix(&mut self) -> EnumResult<'_, R> { + match try_with!(self.parse_whitespace_in_value(), EnumResult::Error) { + b'{' => { + self.eat_char(); + check_recursion_prefix!(self, EnumResult::Error); + EnumResult::Variant(VariantAccess::new(self)) + } + b'"' => EnumResult::Unit(UnitVariantAccess::new(self)), + _ => EnumResult::Error(self.peek_error(ErrorCode::ExpectedSomeValue)), + } + } + + #[inline] + fn parse_enum_suffix(&mut self) -> Result<()> { + match tri!(self.parse_whitespace_in_object()) { + b'}' => { + self.eat_char(); + Ok(()) + } + _ => Err(self.error(ErrorCode::ExpectedSomeValue)), + } + } + + #[inline] + fn parse_option(&mut self) -> OptionResult { + match try_with!(self.parse_whitespace(), OptionResult::Error) { + Some(b'n') => { + self.eat_char(); + try_with!(self.parse_ident(b"ull"), OptionResult::Error); + OptionResult::None + } + _ => OptionResult::Some, + } + } + + /// Returns the first non-whitespace byte without consuming it, or `Err` if + /// EOF is encountered. + fn parse_whitespace_in_value(&mut self) -> Result { + match tri!(self.parse_whitespace()) { + Some(b) => Ok(b), + None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + fn parse_whitespace_until_null(&mut self, visitor: &dyn Expected) -> Result<()> { + tri!(self.parse_whitespace_until(b'n', visitor)); + + self.parse_ident(b"ull") + } + + #[inline] + fn parse_whitespace_until(&mut self, expected: u8, visitor: &dyn Expected) -> Result<()> { + if tri!(self.parse_whitespace_in_value()) == expected { + self.eat_char(); + Ok(()) + } else { + Err(self.peek_invalid_type(visitor)) + } + } + + /// Returns the first non-whitespace byte without consuming it, or `Err` if + /// EOF is encountered. + fn parse_whitespace_in_object(&mut self) -> Result { + match tri!(self.parse_whitespace()) { + Some(b) => Ok(b), + None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + /// Returns the first non-whitespace byte without consuming it, or `None` if /// EOF is encountered. fn parse_whitespace(&mut self) -> Result> { @@ -293,14 +541,10 @@ impl<'de, R: Read<'de>> Deserializer { Ok(n) => n.invalid_type(exp), Err(err) => return err, }, - b'"' => { - self.eat_char(); - self.scratch.clear(); - match self.read.parse_str(&mut self.scratch) { - Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), - Err(err) => return err, - } - } + b'"' => match self.parse_str() { + Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), + Err(err) => return err, + }, b'[' => de::Error::invalid_type(Unexpected::Seq, exp), b'{' => de::Error::invalid_type(Unexpected::Map, exp), _ => self.peek_error(ErrorCode::ExpectedSomeValue), @@ -313,21 +557,7 @@ impl<'de, R: Read<'de>> Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'-' => { - self.eat_char(); - tri!(self.parse_integer(false)).visit(visitor) - } - b'0'..=b'9' => tri!(self.parse_integer(true)).visit(visitor), - _ => Err(self.peek_invalid_type(&visitor)), - }; + let value = tri!(self.parse_number_prefix(&visitor)).visit(visitor); match value { Ok(value) => Ok(value), @@ -370,15 +600,9 @@ impl<'de, R: Read<'de>> Deserializer { fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { for expected in ident { - match tri!(self.next_char()) { - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - Some(next) => { - if next != *expected { - return Err(self.error(ErrorCode::ExpectedSomeIdent)); - } - } + let next = tri!(self.next_char_or_error()); + if next != *expected { + return Err(self.error(ErrorCode::ExpectedSomeIdent)); } } @@ -386,12 +610,7 @@ impl<'de, R: Read<'de>> Deserializer { } fn parse_integer(&mut self, positive: bool) -> Result { - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - }; + let next = tri!(self.next_char_or_error()); match next { b'0' => { @@ -507,12 +726,7 @@ impl<'de, R: Read<'de>> Deserializer { _ => true, }; - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - }; + let next = tri!(self.next_char_or_error()); // Make sure a digit follows the exponent place. let mut exp = match next { @@ -699,12 +913,7 @@ impl<'de, R: Read<'de>> Deserializer { _ => true, }; - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - }; + let next = tri!(self.next_char_or_error()); // Make sure a digit follows the exponent place. let mut exp = match next { @@ -878,13 +1087,9 @@ impl<'de, R: Read<'de>> Deserializer { #[cfg(feature = "arbitrary_precision")] fn scan_or_eof(&mut self, buf: &mut String) -> Result { - match tri!(self.next_char()) { - Some(b) => { - buf.push(b as char); - Ok(b) - } - None => Err(self.error(ErrorCode::EofWhileParsingValue)), - } + let b = tri!(self.next_char_or_error()); + buf.push(b as char); + Ok(b) } #[cfg(feature = "arbitrary_precision")] @@ -980,17 +1185,19 @@ impl<'de, R: Read<'de>> Deserializer { } fn parse_object_colon(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(b':') => { + match tri!(self.parse_whitespace_in_object()) { + b':' => { self.eat_char(); Ok(()) } - Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + _ => Err(self.peek_error(ErrorCode::ExpectedColon)), } } - fn end_seq(&mut self) -> Result<()> { + fn end_recursion_and_seq(&mut self) -> Result<()> { + if_checking_recursion_limit! { + self.remaining_depth += 1; + } match tri!(self.parse_whitespace()) { Some(b']') => { self.eat_char(); @@ -1008,15 +1215,17 @@ impl<'de, R: Read<'de>> Deserializer { } } - fn end_map(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(b'}') => { + fn end_recursion_and_map(&mut self) -> Result<()> { + if_checking_recursion_limit! { + self.remaining_depth += 1; + } + match tri!(self.parse_whitespace_in_object()) { + b'}' => { self.eat_char(); Ok(()) } - Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)), - Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + b',' => Err(self.peek_error(ErrorCode::TrailingComma)), + _ => Err(self.peek_error(ErrorCode::TrailingCharacters)), } } @@ -1025,12 +1234,7 @@ impl<'de, R: Read<'de>> Deserializer { let mut enclosing = None; loop { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + let peek = tri!(self.parse_whitespace_in_value()); let frame = match peek { b'n' => { @@ -1118,16 +1322,14 @@ impl<'de, R: Read<'de>> Deserializer { } if frame == b'{' { - match tri!(self.parse_whitespace()) { - Some(b'"') => self.eat_char(), - Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + match tri!(self.parse_whitespace_in_object()) { + b'"' => self.eat_char(), + _ => return Err(self.peek_error(ErrorCode::KeyMustBeAString)), } tri!(self.read.ignore_str()); - match tri!(self.parse_whitespace()) { - Some(b':') => self.eat_char(), - Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + match tri!(self.parse_whitespace_in_object()) { + b':' => self.eat_char(), + _ => return Err(self.peek_error(ErrorCode::ExpectedColon)), } } @@ -1270,39 +1472,6 @@ macro_rules! deserialize_number { }; } -#[cfg(not(feature = "unbounded_depth"))] -macro_rules! if_checking_recursion_limit { - ($($body:tt)*) => { - $($body)* - }; -} - -#[cfg(feature = "unbounded_depth")] -macro_rules! if_checking_recursion_limit { - ($this:ident $($body:tt)*) => { - if !$this.disable_recursion_limit { - $this $($body)* - } - }; -} - -macro_rules! check_recursion { - ($this:ident $($body:tt)*) => { - if_checking_recursion_limit! { - $this.remaining_depth -= 1; - if $this.remaining_depth == 0 { - return Err($this.peek_error(ErrorCode::RecursionLimitExceeded)); - } - } - - $this $($body)* - - if_checking_recursion_limit! { - $this.remaining_depth += 1; - } - }; -} - impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { type Error = Error; @@ -1311,65 +1480,29 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'n' => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - b't' => { - self.eat_char(); - tri!(self.parse_ident(b"rue")); - visitor.visit_bool(true) - } - b'f' => { - self.eat_char(); - tri!(self.parse_ident(b"alse")); - visitor.visit_bool(false) - } - b'-' => { - self.eat_char(); - tri!(self.parse_any_number(false)).visit(visitor) - } - b'0'..=b'9' => tri!(self.parse_any_number(true)).visit(visitor), - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str(&mut self.scratch)) { - Reference::Borrowed(s) => visitor.visit_borrowed_str(s), - Reference::Copied(s) => visitor.visit_str(s), - } - } - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { + let value = match self.parse_any_prefix() { + AnyResult::Null => visitor.visit_unit(), + AnyResult::Bool(b) => visitor.visit_bool(b), + AnyResult::Number(positive) => tri!(self.parse_any_number(positive)).visit(visitor), + AnyResult::BorrowedString(s) => visitor.visit_borrowed_str(s), + AnyResult::CopiedString(s) => visitor.visit_str(s), + AnyResult::Array => { + let ret = visitor.visit_seq(SeqAccess::new(self)); + + match (ret, self.end_recursion_and_seq()) { (Ok(ret), Ok(())) => Ok(ret), (Err(err), _) | (_, Err(err)) => Err(err), } } - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } + AnyResult::Map => { + let ret = visitor.visit_map(MapAccess::new(self)); - match (ret, self.end_map()) { + match (ret, self.end_recursion_and_map()) { (Ok(ret), Ok(())) => Ok(ret), (Err(err), _) | (_, Err(err)) => Err(err), } } - _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + AnyResult::Error(err) => Err(err), }; match value { @@ -1387,12 +1520,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + let peek = tri!(self.parse_whitespace_in_value()); let value = match peek { b't' => { @@ -1444,16 +1572,10 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { { let mut buf = String::new(); - match tri!(self.parse_whitespace()) { - Some(b'-') => { - self.eat_char(); - buf.push('-'); - } - Some(_) => {} - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + if tri!(self.parse_whitespace_in_value()) == b'-' { + self.eat_char(); + buf.push('-'); + } tri!(self.scan_integer128(&mut buf)); @@ -1474,14 +1596,8 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - match tri!(self.parse_whitespace()) { - Some(b'-') => { - return Err(self.peek_error(ErrorCode::NumberOutOfRange)); - } - Some(_) => {} - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } + if tri!(self.parse_whitespace_in_value()) == b'-' { + return Err(self.peek_error(ErrorCode::NumberOutOfRange)); } let mut buf = String::new(); @@ -1508,27 +1624,14 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { self.deserialize_str(visitor) } + #[inline] fn deserialize_str(self, visitor: V) -> Result where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str(&mut self.scratch)) { - Reference::Borrowed(s) => visitor.visit_borrowed_str(s), - Reference::Copied(s) => visitor.visit_str(s), - } - } - _ => Err(self.peek_invalid_type(&visitor)), + let value = match tri!(self.parse_str_prefix(&visitor)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), }; match value { @@ -1618,22 +1721,13 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + let peek = tri!(self.parse_whitespace_in_value()); let value = match peek { - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str_raw(&mut self.scratch)) { - Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), - Reference::Copied(b) => visitor.visit_bytes(b), - } - } + b'"' => match tri!(self.parse_str_raw()) { + Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), + Reference::Copied(b) => visitor.visit_bytes(b), + }, b'[' => self.deserialize_seq(visitor), _ => Err(self.peek_invalid_type(&visitor)), }; @@ -1658,37 +1752,21 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - match tri!(self.parse_whitespace()) { - Some(b'n') => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_none() - } - _ => visitor.visit_some(self), + match self.parse_option() { + OptionResult::Some => visitor.visit_some(self), + OptionResult::None => visitor.visit_none(), + OptionResult::Error(err) => Err(err), } } + #[inline] fn deserialize_unit(self, visitor: V) -> Result where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'n' => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - _ => Err(self.peek_invalid_type(&visitor)), - }; + tri!(self.parse_whitespace_until_null(&visitor)); - match value { + match visitor.visit_unit() { Ok(value) => Ok(value), Err(err) => Err(self.fix_position(err)), } @@ -1722,31 +1800,13 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + tri!(self.parse_seq_prefix(&visitor)); - let value = match peek { - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; + let ret = visitor.visit_seq(SeqAccess::new(self)); - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), + match (ret, self.end_recursion_and_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(self.fix_position(err)), } } @@ -1773,34 +1833,17 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; + tri!(self.parse_map_prefix(&visitor)); - let value = match peek { - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } + let ret = visitor.visit_map(MapAccess::new(self)); - match (ret, self.end_map()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), + match (ret, self.end_recursion_and_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(self.fix_position(err)), } } + #[inline] fn deserialize_struct( self, _name: &'static str, @@ -1810,42 +1853,17 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + let (ret, ret2) = match self.parse_struct_prefix(&visitor) { + StructResult::Array(access) => { + (visitor.visit_seq(access), self.end_recursion_and_seq()) } + StructResult::Map(access) => (visitor.visit_map(access), self.end_recursion_and_map()), + StructResult::Error(err) => return Err(err), }; - let value = match peek { - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } - - match (ret, self.end_map()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), + match (ret, ret2) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(self.fix_position(err)), } } @@ -1861,25 +1879,14 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { where V: de::Visitor<'de>, { - match tri!(self.parse_whitespace()) { - Some(b'{') => { - check_recursion! { - self.eat_char(); - let value = tri!(visitor.visit_enum(VariantAccess::new(self))); - } - - match tri!(self.parse_whitespace()) { - Some(b'}') => { - self.eat_char(); - Ok(value) - } - Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)), - None => Err(self.error(ErrorCode::EofWhileParsingObject)), - } + match self.parse_enum_prefix() { + EnumResult::Variant(variant) => { + let value = tri!(visitor.visit_enum(variant)); + tri!(self.parse_enum_suffix()); + Ok(value) } - Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)), - Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + EnumResult::Unit(unit) => visitor.visit_enum(unit), + EnumResult::Error(err) => Err(err), } } @@ -1910,42 +1917,63 @@ impl<'a, R: 'a> SeqAccess<'a, R> { } } -impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { - type Error = Error; +enum ElementResult { + Error(Error), + Field, + Done, +} - fn next_element_seed(&mut self, seed: T) -> Result> - where - T: de::DeserializeSeed<'de>, - { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b']') => { - return Ok(None); +impl<'de, 'a, R: Read<'de> + 'a> SeqAccess<'a, R> { + fn parse_element_prefix(&mut self) -> ElementResult { + let peek = match try_with!(self.de.parse_whitespace(), ElementResult::Error) { + Some(peek) => peek, + None => { + return ElementResult::Error(self.de.peek_error(ErrorCode::EofWhileParsingList)); + } + }; + let peek = match peek { + b']' => { + return ElementResult::Done; } - Some(b',') if !self.first => { + b',' if !self.first => { self.de.eat_char(); - tri!(self.de.parse_whitespace()) + try_with!(self.de.parse_whitespace_in_value(), ElementResult::Error) } - Some(b) => { + b => { if self.first { self.first = false; - Some(b) + b } else { - return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + return ElementResult::Error( + self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd), + ); } } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); - } }; match peek { - Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))), - None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + b']' => ElementResult::Error(self.de.peek_error(ErrorCode::TrailingComma)), + _ => ElementResult::Field, } } } +impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { + type Error = Error; + + #[inline] + fn next_element_seed(&mut self, seed: T) -> Result> + where + T: de::DeserializeSeed<'de>, + { + Ok(match self.parse_element_prefix() { + ElementResult::Field => Some(tri!(seed.deserialize(&mut *self.de))), + ElementResult::Done => None, + ElementResult::Error(err) => return Err(err), + }) + } +} + struct MapAccess<'a, R: 'a> { de: &'a mut Deserializer, first: bool, @@ -1957,42 +1985,58 @@ impl<'a, R: 'a> MapAccess<'a, R> { } } -impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> { - type Error = Error; +enum KeyResult { + Error(Error), + Key, + Done, +} - fn next_key_seed(&mut self, seed: K) -> Result> - where - K: de::DeserializeSeed<'de>, - { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b'}') => { - return Ok(None); +impl<'de, 'a, R: Read<'de> + 'a> MapAccess<'a, R> { + fn parse_key_prefix(&mut self) -> KeyResult { + let peek = match try_with!(self.de.parse_whitespace_in_object(), KeyResult::Error) { + b'}' => { + return KeyResult::Done; } - Some(b',') if !self.first => { + b',' if !self.first => { self.de.eat_char(); - tri!(self.de.parse_whitespace()) + try_with!(self.de.parse_whitespace_in_value(), KeyResult::Error) } - Some(b) => { + b => { if self.first { self.first = false; - Some(b) + b } else { - return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + return KeyResult::Error( + self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd), + ); } } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); - } }; match peek { - Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), - Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), - None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + b'"' => KeyResult::Key, + b'}' => KeyResult::Error(self.de.peek_error(ErrorCode::TrailingComma)), + _ => KeyResult::Error(self.de.peek_error(ErrorCode::KeyMustBeAString)), } } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> { + type Error = Error; + #[inline] + fn next_key_seed(&mut self, seed: K) -> Result> + where + K: de::DeserializeSeed<'de>, + { + Ok(match self.parse_key_prefix() { + KeyResult::Key => Some(tri!(seed.deserialize(MapKey { de: &mut *self.de }))), + KeyResult::Done => None, + KeyResult::Error(err) => return Err(err), + }) + } + + #[inline] fn next_value_seed(&mut self, seed: V) -> Result where V: de::DeserializeSeed<'de>, @@ -2129,9 +2173,7 @@ macro_rules! deserialize_integer_key { where V: de::Visitor<'de>, { - self.de.eat_char(); - self.de.scratch.clear(); - let string = tri!(self.de.read.parse_str(&mut self.de.scratch)); + let string = tri!(self.de.parse_str()); match (string.parse(), string) { (Ok(integer), _) => visitor.$visit(integer), (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), @@ -2152,9 +2194,7 @@ where where V: de::Visitor<'de>, { - self.de.eat_char(); - self.de.scratch.clear(); - match tri!(self.de.read.parse_str(&mut self.de.scratch)) { + match tri!(self.de.parse_str()) { Reference::Borrowed(s) => visitor.visit_borrowed_str(s), Reference::Copied(s) => visitor.visit_str(s), } diff --git a/src/ser.rs b/src/ser.rs index 64cb00e1a..22b2d0c69 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -1,13 +1,23 @@ //! Serialize a Rust data structure into JSON data. -use crate::error::{Error, ErrorCode, Result}; -use crate::io; -use alloc::string::{String, ToString}; -use alloc::vec::Vec; -use core::fmt::{self, Display}; -use core::num::FpCategory; -use serde::ser::{self, Impossible, Serialize}; -use serde::serde_if_integer128; +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; +use core::{ + fmt::{self, Display}, + num::FpCategory, +}; + +use serde::{ + ser::{self, Impossible, Serialize, Serializer as _}, + serde_if_integer128, +}; + +use crate::{ + error::{Error, ErrorCode, Result}, + io, +}; /// A structure for serializing Rust values into JSON. #[cfg_attr(docsrs, doc(cfg(feature = "std")))] @@ -55,6 +65,106 @@ where pub fn into_inner(self) -> W { self.writer } + + fn begin_string(&mut self) -> Result<()> { + self.formatter + .begin_string(&mut self.writer) + .map_err(Error::io) + } + + fn end_string(&mut self) -> Result<()> { + self.formatter + .end_string(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn begin_object_key(&mut self, first: bool) -> Result<()> { + self.formatter + .begin_object_key(&mut self.writer, first) + .map_err(Error::io) + } + + #[inline] + fn end_object_key(&mut self) -> Result<()> { + self.formatter + .end_object_key(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn begin_object(&mut self) -> Result<()> { + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn begin_object_value(&mut self) -> Result<()> { + self.formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn end_object_value(&mut self) -> Result<()> { + self.formatter + .end_object_value(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn end_object(&mut self) -> Result<()> { + self.formatter + .end_object(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn begin_array(&mut self) -> Result<()> { + self.formatter + .begin_array(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn begin_array_value(&mut self, first: bool) -> Result<()> { + self.formatter + .begin_array_value(&mut self.writer, first) + .map_err(Error::io) + } + + #[inline] + fn end_array_value(&mut self) -> Result<()> { + self.formatter + .end_array_value(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn end_array(&mut self) -> Result<()> { + self.formatter + .end_array(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn write_null(&mut self) -> Result<()> { + self.formatter + .write_null(&mut self.writer) + .map_err(Error::io) + } + + fn serialize_variant(&mut self, variant: &'static str) -> Result<()> { + tri!(self + .formatter + .begin_object(&mut self.writer) + .map_err(Error::io)); + tri!(self.begin_object_key(true)); + tri!(self.serialize_str(variant)); + tri!(self.end_object_key()); + self.begin_object_value() + } } impl<'a, W, F> ser::Serializer for &'a mut Serializer @@ -75,47 +185,37 @@ where #[inline] fn serialize_bool(self, value: bool) -> Result<()> { - tri!(self - .formatter + self.formatter .write_bool(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_i8(self, value: i8) -> Result<()> { - tri!(self - .formatter + self.formatter .write_i8(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_i16(self, value: i16) -> Result<()> { - tri!(self - .formatter + self.formatter .write_i16(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_i32(self, value: i32) -> Result<()> { - tri!(self - .formatter + self.formatter .write_i32(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_i64(self, value: i64) -> Result<()> { - tri!(self - .formatter + self.formatter .write_i64(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } serde_if_integer128! { @@ -128,38 +228,30 @@ where #[inline] fn serialize_u8(self, value: u8) -> Result<()> { - tri!(self - .formatter + self.formatter .write_u8(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_u16(self, value: u16) -> Result<()> { - tri!(self - .formatter + self.formatter .write_u16(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_u32(self, value: u32) -> Result<()> { - tri!(self - .formatter + self.formatter .write_u32(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } #[inline] fn serialize_u64(self, value: u64) -> Result<()> { - tri!(self - .formatter + self.formatter .write_u64(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) + .map_err(Error::io) } serde_if_integer128! { @@ -173,39 +265,23 @@ where #[inline] fn serialize_f32(self, value: f32) -> Result<()> { match value.classify() { - FpCategory::Nan | FpCategory::Infinite => { - tri!(self - .formatter - .write_null(&mut self.writer) - .map_err(Error::io)); - } - _ => { - tri!(self - .formatter - .write_f32(&mut self.writer, value) - .map_err(Error::io)); - } + FpCategory::Nan | FpCategory::Infinite => self.write_null(), + _ => self + .formatter + .write_f32(&mut self.writer, value) + .map_err(Error::io), } - Ok(()) } #[inline] fn serialize_f64(self, value: f64) -> Result<()> { match value.classify() { - FpCategory::Nan | FpCategory::Infinite => { - tri!(self - .formatter - .write_null(&mut self.writer) - .map_err(Error::io)); - } - _ => { - tri!(self - .formatter - .write_f64(&mut self.writer, value) - .map_err(Error::io)); - } + FpCategory::Nan | FpCategory::Infinite => self.write_null(), + _ => self + .formatter + .write_f64(&mut self.writer, value) + .map_err(Error::io), } - Ok(()) } #[inline] @@ -217,8 +293,7 @@ where #[inline] fn serialize_str(self, value: &str) -> Result<()> { - tri!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io)); - Ok(()) + format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io) } #[inline] @@ -233,11 +308,7 @@ where #[inline] fn serialize_unit(self) -> Result<()> { - tri!(self - .formatter - .write_null(&mut self.writer) - .map_err(Error::io)); - Ok(()) + self.write_null() } #[inline] @@ -275,33 +346,10 @@ where where T: ?Sized + Serialize, { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); + tri!(self.serialize_variant(variant)); tri!(value.serialize(&mut *self)); - tri!(self - .formatter - .end_object_value(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .end_object(&mut self.writer) - .map_err(Error::io)); - Ok(()) + tri!(self.end_object_value()); + self.end_object() } #[inline] @@ -319,15 +367,9 @@ where #[inline] fn serialize_seq(self, len: Option) -> Result { - tri!(self - .formatter - .begin_array(&mut self.writer) - .map_err(Error::io)); + tri!(self.begin_array()); if len == Some(0) { - tri!(self - .formatter - .end_array(&mut self.writer) - .map_err(Error::io)); + tri!(self.end_array()); Ok(Compound::Map { ser: self, state: State::Empty, @@ -362,37 +404,15 @@ where variant: &'static str, len: usize, ) -> Result { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); + tri!(self.serialize_variant(variant)); self.serialize_seq(Some(len)) } #[inline] fn serialize_map(self, len: Option) -> Result { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); + tri!(self.begin_object()); if len == Some(0) { - tri!(self - .formatter - .end_object(&mut self.writer) - .map_err(Error::io)); + tri!(self.end_object()); Ok(Compound::Map { ser: self, state: State::Empty, @@ -424,23 +444,7 @@ where variant: &'static str, len: usize, ) -> Result { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); + tri!(self.serialize_variant(variant)); self.serialize_map(Some(len)) } @@ -473,10 +477,7 @@ where } } - tri!(self - .formatter - .begin_string(&mut self.writer) - .map_err(Error::io)); + tri!(self.begin_string()); { let mut adapter = Adapter { writer: &mut self.writer, @@ -490,11 +491,7 @@ where } } } - tri!(self - .formatter - .end_string(&mut self.writer) - .map_err(Error::io)); - Ok(()) + self.end_string() } } @@ -535,17 +532,10 @@ where { match self { Compound::Map { ser, state } => { - tri!(ser - .formatter - .begin_array_value(&mut ser.writer, *state == State::First) - .map_err(Error::io)); + tri!(ser.begin_array_value(*state == State::First)); *state = State::Rest; tri!(value.serialize(&mut **ser)); - tri!(ser - .formatter - .end_array_value(&mut ser.writer) - .map_err(Error::io)); - Ok(()) + ser.end_array_value() } #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), @@ -557,13 +547,10 @@ where #[inline] fn end(self) -> Result<()> { match self { - Compound::Map { ser, state } => { - match state { - State::Empty => {} - _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)), - } - Ok(()) - } + Compound::Map { ser, state } => match state { + State::Empty => Ok(()), + _ => ser.end_array(), + }, #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), #[cfg(feature = "raw_value")] @@ -638,14 +625,10 @@ where Compound::Map { ser, state } => { match state { State::Empty => {} - _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)), + _ => tri!(ser.end_array()), } - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); - Ok(()) + tri!(ser.end_object_value()); + ser.end_object() } #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), @@ -670,19 +653,12 @@ where { match self { Compound::Map { ser, state } => { - tri!(ser - .formatter - .begin_object_key(&mut ser.writer, *state == State::First) - .map_err(Error::io)); + tri!(ser.begin_object_key(*state == State::First)); *state = State::Rest; tri!(key.serialize(MapKeySerializer { ser: *ser })); - tri!(ser - .formatter - .end_object_key(&mut ser.writer) - .map_err(Error::io)); - Ok(()) + ser.end_object_key() } #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), @@ -698,16 +674,9 @@ where { match self { Compound::Map { ser, .. } => { - tri!(ser - .formatter - .begin_object_value(&mut ser.writer) - .map_err(Error::io)); + tri!(ser.begin_object_value()); tri!(value.serialize(&mut **ser)); - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - Ok(()) + ser.end_object_value() } #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), @@ -719,13 +688,10 @@ where #[inline] fn end(self) -> Result<()> { match self { - Compound::Map { ser, state } => { - match state { - State::Empty => {} - _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)), - } - Ok(()) - } + Compound::Map { ser, state } => match state { + State::Empty => Ok(()), + _ => ser.end_object(), + }, #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), #[cfg(feature = "raw_value")] @@ -752,8 +718,7 @@ where #[cfg(feature = "arbitrary_precision")] Compound::Number { ser, .. } => { if key == crate::number::TOKEN { - tri!(value.serialize(NumberStrEmitter(ser))); - Ok(()) + value.serialize(NumberStrEmitter(ser)) } else { Err(invalid_number()) } @@ -761,8 +726,7 @@ where #[cfg(feature = "raw_value")] Compound::RawValue { ser, .. } => { if key == crate::raw::TOKEN { - tri!(value.serialize(RawValueStrEmitter(ser))); - Ok(()) + value.serialize(RawValueStrEmitter(ser)) } else { Err(invalid_raw_value()) } @@ -810,14 +774,10 @@ where Compound::Map { ser, state } => { match state { State::Empty => {} - _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)), + _ => tri!(ser.end_object()), } - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); - Ok(()) + tri!(ser.end_object_value()); + ser.end_object() } #[cfg(feature = "arbitrary_precision")] Compound::Number { .. } => unreachable!(), @@ -889,196 +849,106 @@ where } fn serialize_i8(self, value: i8) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_i8(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_i16(self, value: i16) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_i16(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_i32(self, value: i32) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_i32(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_i64(self, value: i64) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_i64(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } serde_if_integer128! { fn serialize_i128(self, value: i128) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_number_str(&mut self.ser.writer, &value.to_string()) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } } fn serialize_u8(self, value: u8) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_u8(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_u16(self, value: u16) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_u16(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_u32(self, value: u32) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_u32(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } fn serialize_u64(self, value: u64) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_u64(&mut self.ser.writer, value) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } serde_if_integer128! { fn serialize_u128(self, value: u128) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); + tri!(self.ser.begin_string()); tri!(self .ser .formatter .write_number_str(&mut self.ser.writer, &value.to_string()) .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) + self.ser.end_string() } } @@ -1774,7 +1644,8 @@ pub trait Formatter { { use self::CharEscape::*; - let s = match char_escape { + let bytes; + let s: &[u8] = match char_escape { Quote => b"\\\"", ReverseSolidus => b"\\\\", Solidus => b"\\/", @@ -1785,7 +1656,7 @@ pub trait Formatter { Tab => b"\\t", AsciiControl(byte) => { static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; - let bytes = &[ + bytes = [ b'\\', b'u', b'0', @@ -1793,7 +1664,7 @@ pub trait Formatter { HEX_DIGITS[(byte >> 4) as usize], HEX_DIGITS[(byte & 0xF) as usize], ]; - return writer.write_all(bytes); + &bytes } }; @@ -1985,13 +1856,8 @@ impl<'a> Formatter for PrettyFormatter<'a> { where W: ?Sized + io::Write, { - if first { - tri!(writer.write_all(b"\n")); - } else { - tri!(writer.write_all(b",\n")); - } - tri!(indent(writer, self.current_indent, self.indent)); - Ok(()) + tri!(writer.write_all(if first { b"\n" } else { b",\n" })); + indent(writer, self.current_indent, self.indent) } #[inline] @@ -2033,11 +1899,7 @@ impl<'a> Formatter for PrettyFormatter<'a> { where W: ?Sized + io::Write, { - if first { - tri!(writer.write_all(b"\n")); - } else { - tri!(writer.write_all(b",\n")); - } + tri!(writer.write_all(if first { b"\n" } else { b",\n" })); indent(writer, self.current_indent, self.indent) } @@ -2066,8 +1928,7 @@ where { tri!(formatter.begin_string(writer)); tri!(format_escaped_str_contents(writer, formatter, value)); - tri!(formatter.end_string(writer)); - Ok(()) + formatter.end_string(writer) } fn format_escaped_str_contents( @@ -2152,8 +2013,7 @@ where T: ?Sized + Serialize, { let mut ser = Serializer::new(writer); - tri!(value.serialize(&mut ser)); - Ok(()) + value.serialize(&mut ser) } /// Serialize the given data structure as pretty-printed JSON into the IO @@ -2171,8 +2031,7 @@ where T: ?Sized + Serialize, { let mut ser = Serializer::pretty(writer); - tri!(value.serialize(&mut ser)); - Ok(()) + value.serialize(&mut ser) } /// Serialize the given data structure as a JSON byte vector.