From 8dd16259287f58f9273002717ec4d27e97127719 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:43:14 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- third_party/rust/serde_json/src/de.rs | 295 +++++++++++++-------- third_party/rust/serde_json/src/error.rs | 128 +++++++-- .../rust/serde_json/src/features_check/error.rs | 1 - .../rust/serde_json/src/features_check/mod.rs | 13 - third_party/rust/serde_json/src/io/core.rs | 2 +- .../rust/serde_json/src/lexical/algorithm.rs | 5 +- third_party/rust/serde_json/src/lexical/bignum.rs | 1 + third_party/rust/serde_json/src/lexical/digit.rs | 5 +- third_party/rust/serde_json/src/lexical/errors.rs | 3 +- .../rust/serde_json/src/lexical/exponent.rs | 4 +- .../rust/serde_json/src/lexical/large_powers32.rs | 2 +- .../rust/serde_json/src/lexical/large_powers64.rs | 2 +- third_party/rust/serde_json/src/lexical/math.rs | 4 +- third_party/rust/serde_json/src/lexical/num.rs | 13 +- .../rust/serde_json/src/lexical/rounding.rs | 2 +- third_party/rust/serde_json/src/lib.rs | 35 +-- third_party/rust/serde_json/src/macros.rs | 3 +- third_party/rust/serde_json/src/map.rs | 131 ++++++--- third_party/rust/serde_json/src/number.rs | 76 +++++- third_party/rust/serde_json/src/raw.rs | 270 ++++++++++++++++++- third_party/rust/serde_json/src/read.rs | 6 +- third_party/rust/serde_json/src/ser.rs | 122 +++++++-- third_party/rust/serde_json/src/value/de.rs | 94 +++++-- third_party/rust/serde_json/src/value/from.rs | 37 +-- third_party/rust/serde_json/src/value/index.rs | 2 +- third_party/rust/serde_json/src/value/mod.rs | 30 ++- .../rust/serde_json/src/value/partial_eq.rs | 14 +- third_party/rust/serde_json/src/value/ser.rs | 41 +-- 28 files changed, 1003 insertions(+), 338 deletions(-) delete mode 100644 third_party/rust/serde_json/src/features_check/error.rs delete mode 100644 third_party/rust/serde_json/src/features_check/mod.rs (limited to 'third_party/rust/serde_json/src') diff --git a/third_party/rust/serde_json/src/de.rs b/third_party/rust/serde_json/src/de.rs index 88d0f2624d..c7774f6873 100644 --- a/third_party/rust/serde_json/src/de.rs +++ b/third_party/rust/serde_json/src/de.rs @@ -22,6 +22,7 @@ use crate::number::NumberDeserializer; pub use crate::read::{Read, SliceRead, StrRead}; #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub use crate::read::IoRead; ////////////////////////////////////////////////////////////////////////////// @@ -209,7 +210,7 @@ impl<'de, R: Read<'de>> Deserializer { self.disable_recursion_limit = true; } - fn peek(&mut self) -> Result> { + pub(crate) fn peek(&mut self) -> Result> { self.read.peek() } @@ -248,7 +249,7 @@ impl<'de, R: Read<'de>> Deserializer { fn parse_whitespace(&mut self) -> Result> { loop { match tri!(self.peek()) { - Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => { + Some(b' ' | b'\n' | b'\t' | b'\r') => { self.eat_char(); } other => { @@ -309,9 +310,9 @@ impl<'de, R: Read<'de>> Deserializer { self.fix_position(err) } - fn deserialize_number(&mut self, visitor: V) -> Result + pub(crate) fn deserialize_number<'any, V>(&mut self, visitor: V) -> Result where - V: de::Visitor<'de>, + V: de::Visitor<'any>, { let peek = match tri!(self.parse_whitespace()) { Some(b) => b, @@ -335,6 +336,79 @@ impl<'de, R: Read<'de>> Deserializer { } } + #[cfg(feature = "float_roundtrip")] + pub(crate) fn do_deserialize_f32<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + self.single_precision = true; + let val = self.deserialize_number(visitor); + self.single_precision = false; + val + } + + pub(crate) fn do_deserialize_i128<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + 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)); + } + }; + + tri!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_i128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + pub(crate) fn do_deserialize_u128<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + match tri!(self.parse_whitespace()) { + Some(b'-') => { + return Err(self.peek_error(ErrorCode::NumberOutOfRange)); + } + Some(_) => {} + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + } + + let mut buf = String::new(); + tri!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_u128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + fn scan_integer128(&mut self, buf: &mut String) -> Result<()> { match tri!(self.next_char_or_null()) { b'0' => { @@ -407,7 +481,7 @@ impl<'de, R: Read<'de>> Deserializer { // try to keep the number as a `u64` until we grow // too large. At that point, switch to parsing the // value as a `f64`. - if overflow!(significand * 10 + digit, u64::max_value()) { + if overflow!(significand * 10 + digit, u64::MAX) { return Ok(ParserNumber::F64(tri!( self.parse_long_integer(positive, significand), ))); @@ -459,7 +533,7 @@ impl<'de, R: Read<'de>> Deserializer { while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { let digit = (c - b'0') as u64; - if overflow!(significand * 10 + digit, u64::max_value()) { + if overflow!(significand * 10 + digit, u64::MAX) { let exponent = exponent_before_decimal_point + exponent_after_decimal_point; return self.parse_decimal_overflow(positive, significand, exponent); } @@ -523,7 +597,7 @@ impl<'de, R: Read<'de>> Deserializer { self.eat_char(); let digit = (c - b'0') as i32; - if overflow!(exp * 10 + digit, i32::max_value()) { + if overflow!(exp * 10 + digit, i32::MAX) { let zero_significand = significand == 0; return self.parse_exponent_overflow(positive, zero_significand, positive_exp); } @@ -715,7 +789,7 @@ impl<'de, R: Read<'de>> Deserializer { self.eat_char(); let digit = (c - b'0') as i32; - if overflow!(exp * 10 + digit, i32::max_value()) { + if overflow!(exp * 10 + digit, i32::MAX) { let zero_significand = self.scratch.iter().all(|&digit| digit == b'0'); return self.parse_exponent_overflow(positive, zero_significand, positive_exp); } @@ -860,7 +934,7 @@ impl<'de, R: Read<'de>> Deserializer { if !positive { buf.push('-'); } - self.scan_integer(&mut buf)?; + tri!(self.scan_integer(&mut buf)); if positive { if let Ok(unsigned) = buf.parse() { return Ok(ParserNumber::U64(unsigned)); @@ -913,7 +987,7 @@ impl<'de, R: Read<'de>> Deserializer { fn scan_number(&mut self, buf: &mut String) -> Result<()> { match tri!(self.peek_or_null()) { b'.' => self.scan_decimal(buf), - e @ b'e' | e @ b'E' => self.scan_exponent(e as char, buf), + e @ (b'e' | b'E') => self.scan_exponent(e as char, buf), _ => Ok(()), } } @@ -938,7 +1012,7 @@ impl<'de, R: Read<'de>> Deserializer { } match tri!(self.peek_or_null()) { - e @ b'e' | e @ b'E' => self.scan_exponent(e as char, buf), + e @ (b'e' | b'E') => self.scan_exponent(e as char, buf), _ => Ok(()), } } @@ -1059,7 +1133,7 @@ impl<'de, R: Read<'de>> Deserializer { tri!(self.read.ignore_str()); None } - frame @ b'[' | frame @ b'{' => { + frame @ (b'[' | b'{') => { self.scratch.extend(enclosing.take()); self.eat_char(); Some(frame) @@ -1204,9 +1278,9 @@ impl<'de, R: Read<'de>> Deserializer { where V: de::Visitor<'de>, { - self.parse_whitespace()?; + tri!(self.parse_whitespace()); self.read.begin_raw_buffering(); - self.ignore_value()?; + tri!(self.ignore_value()); self.read.end_raw_buffering(visitor) } } @@ -1258,11 +1332,15 @@ static POW10: [f64; 309] = [ macro_rules! deserialize_number { ($method:ident) => { + deserialize_number!($method, deserialize_number); + }; + + ($method:ident, $using:ident) => { fn $method(self, visitor: V) -> Result where V: de::Visitor<'de>, { - self.deserialize_number(visitor) + self.$using(visitor) } }; } @@ -1424,77 +1502,9 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { deserialize_number!(deserialize_f64); #[cfg(feature = "float_roundtrip")] - fn deserialize_f32(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.single_precision = true; - let val = self.deserialize_number(visitor); - self.single_precision = false; - val - } - - fn deserialize_i128(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - 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)); - } - }; - - tri!(self.scan_integer128(&mut buf)); - - let value = match buf.parse() { - Ok(int) => visitor.visit_i128(int), - Err(_) => { - return Err(self.error(ErrorCode::NumberOutOfRange)); - } - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_u128(self, visitor: V) -> Result - 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)); - } - } - - let mut buf = String::new(); - tri!(self.scan_integer128(&mut buf)); - - let value = match buf.parse() { - Ok(int) => visitor.visit_u128(int), - Err(_) => { - return Err(self.error(ErrorCode::NumberOutOfRange)); - } - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } + deserialize_number!(deserialize_f32, do_deserialize_f32); + deserialize_number!(deserialize_i128, do_deserialize_i128); + deserialize_number!(deserialize_u128, do_deserialize_u128); fn deserialize_char(self, visitor: V) -> Result where @@ -2118,24 +2128,47 @@ struct MapKey<'a, R: 'a> { de: &'a mut Deserializer, } -macro_rules! deserialize_integer_key { - ($method:ident => $visit:ident) => { +macro_rules! deserialize_numeric_key { + ($method:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_number(visitor) + } + }; + + ($method:ident, $delegate:ident) => { fn $method(self, visitor: V) -> Result 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)); - match (string.parse(), string) { - (Ok(integer), _) => visitor.$visit(integer), - (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), - (Err(_), Reference::Copied(s)) => visitor.visit_str(s), + + match tri!(self.de.peek()) { + Some(b'0'..=b'9' | b'-') => {} + _ => return Err(self.de.error(ErrorCode::ExpectedNumericKey)), + } + + let value = tri!(self.de.$delegate(visitor)); + + match tri!(self.de.peek()) { + Some(b'"') => self.de.eat_char(), + _ => return Err(self.de.peek_error(ErrorCode::ExpectedDoubleQuote)), } + + Ok(value) } }; } +impl<'de, 'a, R> MapKey<'a, R> +where + R: Read<'de>, +{ + deserialize_numeric_key!(deserialize_number, deserialize_number); +} + impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R> where R: Read<'de>, @@ -2155,16 +2188,56 @@ where } } - deserialize_integer_key!(deserialize_i8 => visit_i8); - deserialize_integer_key!(deserialize_i16 => visit_i16); - deserialize_integer_key!(deserialize_i32 => visit_i32); - deserialize_integer_key!(deserialize_i64 => visit_i64); - deserialize_integer_key!(deserialize_i128 => visit_i128); - deserialize_integer_key!(deserialize_u8 => visit_u8); - deserialize_integer_key!(deserialize_u16 => visit_u16); - deserialize_integer_key!(deserialize_u32 => visit_u32); - deserialize_integer_key!(deserialize_u64 => visit_u64); - deserialize_integer_key!(deserialize_u128 => visit_u128); + deserialize_numeric_key!(deserialize_i8); + deserialize_numeric_key!(deserialize_i16); + deserialize_numeric_key!(deserialize_i32); + deserialize_numeric_key!(deserialize_i64); + deserialize_numeric_key!(deserialize_i128, deserialize_i128); + deserialize_numeric_key!(deserialize_u8); + deserialize_numeric_key!(deserialize_u16); + deserialize_numeric_key!(deserialize_u32); + deserialize_numeric_key!(deserialize_u64); + deserialize_numeric_key!(deserialize_u128, deserialize_u128); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_numeric_key!(deserialize_f32); + #[cfg(feature = "float_roundtrip")] + deserialize_numeric_key!(deserialize_f32, deserialize_f32); + deserialize_numeric_key!(deserialize_f64); + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + + let peek = match tri!(self.de.next_char()) { + Some(b) => b, + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b't' => { + tri!(self.de.parse_ident(b"rue\"")); + visitor.visit_bool(true) + } + b'f' => { + tri!(self.de.parse_ident(b"alse\"")); + visitor.visit_bool(false) + } + _ => { + self.de.scratch.clear(); + let s = tri!(self.de.read.parse_str(&mut self.de.scratch)); + Err(de::Error::invalid_type(Unexpected::Str(&s), &visitor)) + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.de.fix_position(err)), + } + } #[inline] fn deserialize_option(self, visitor: V) -> Result @@ -2221,8 +2294,8 @@ where } forward_to_deserialize_any! { - bool f32 f64 char str string unit unit_struct seq tuple tuple_struct map - struct identifier ignored_any + char str string unit unit_struct seq tuple tuple_struct map struct + identifier ignored_any } } @@ -2318,8 +2391,8 @@ where fn peek_end_of_value(&mut self) -> Result<()> { match tri!(self.de.peek()) { - Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b'"') | Some(b'[') - | Some(b']') | Some(b'{') | Some(b'}') | Some(b',') | Some(b':') | None => Ok(()), + Some(b' ' | b'\n' | b'\t' | b'\r' | b'"' | b'[' | b']' | b'{' | b'}' | b',' | b':') + | None => Ok(()), Some(_) => { let position = self.de.read.peek_position(); Err(Error::syntax( @@ -2369,7 +2442,7 @@ where if self_delineated_value { Ok(value) } else { - self.peek_end_of_value().map(|_| value) + self.peek_end_of_value().map(|()| value) } } Err(e) => { @@ -2408,9 +2481,9 @@ where Ok(value) } -/// Deserialize an instance of type `T` from an IO stream of JSON. +/// Deserialize an instance of type `T` from an I/O stream of JSON. /// -/// The content of the IO stream is deserialized directly from the stream +/// The content of the I/O stream is deserialized directly from the stream /// without being buffered in memory by serde_json. /// /// When reading from a source against which short reads are not efficient, such diff --git a/third_party/rust/serde_json/src/error.rs b/third_party/rust/serde_json/src/error.rs index 1875ef08b0..fbf9eb14e5 100644 --- a/third_party/rust/serde_json/src/error.rs +++ b/third_party/rust/serde_json/src/error.rs @@ -9,6 +9,8 @@ use core::str::FromStr; use serde::{de, ser}; #[cfg(feature = "std")] use std::error; +#[cfg(feature = "std")] +use std::io::ErrorKind; /// This type represents all possible errors that can occur when serializing or /// deserializing JSON data. @@ -36,15 +38,16 @@ impl Error { /// The first character in the input and any characters immediately /// following a newline character are in column 1. /// - /// Note that errors may occur in column 0, for example if a read from an IO - /// stream fails immediately following a previously read newline character. + /// Note that errors may occur in column 0, for example if a read from an + /// I/O stream fails immediately following a previously read newline + /// character. pub fn column(&self) -> usize { self.err.column } /// Categorizes the cause of this error. /// - /// - `Category::Io` - failure to read or write bytes on an IO stream + /// - `Category::Io` - failure to read or write bytes on an I/O stream /// - `Category::Syntax` - input that is not syntactically valid JSON /// - `Category::Data` - input data that is semantically incorrect /// - `Category::Eof` - unexpected end of the input data @@ -61,12 +64,15 @@ impl Error { | ErrorCode::ExpectedObjectCommaOrEnd | ErrorCode::ExpectedSomeIdent | ErrorCode::ExpectedSomeValue + | ErrorCode::ExpectedDoubleQuote | ErrorCode::InvalidEscape | ErrorCode::InvalidNumber | ErrorCode::NumberOutOfRange | ErrorCode::InvalidUnicodeCodePoint | ErrorCode::ControlCharacterWhileParsingString | ErrorCode::KeyMustBeAString + | ErrorCode::ExpectedNumericKey + | ErrorCode::FloatKeyMustBeFinite | ErrorCode::LoneLeadingSurrogateInHexEscape | ErrorCode::TrailingComma | ErrorCode::TrailingCharacters @@ -76,7 +82,7 @@ impl Error { } /// Returns true if this error was caused by a failure to read or write - /// bytes on an IO stream. + /// bytes on an I/O stream. pub fn is_io(&self) -> bool { self.classify() == Category::Io } @@ -104,12 +110,61 @@ impl Error { pub fn is_eof(&self) -> bool { self.classify() == Category::Eof } + + /// The kind reported by the underlying standard library I/O error, if this + /// error was caused by a failure to read or write bytes on an I/O stream. + /// + /// # Example + /// + /// ``` + /// use serde_json::Value; + /// use std::io::{self, ErrorKind, Read}; + /// use std::process; + /// + /// struct ReaderThatWillTimeOut<'a>(&'a [u8]); + /// + /// impl<'a> Read for ReaderThatWillTimeOut<'a> { + /// fn read(&mut self, buf: &mut [u8]) -> io::Result { + /// if self.0.is_empty() { + /// Err(io::Error::new(ErrorKind::TimedOut, "timed out")) + /// } else { + /// self.0.read(buf) + /// } + /// } + /// } + /// + /// fn main() { + /// let reader = ReaderThatWillTimeOut(br#" {"k": "#); + /// + /// let _: Value = match serde_json::from_reader(reader) { + /// Ok(value) => value, + /// Err(error) => { + /// if error.io_error_kind() == Some(ErrorKind::TimedOut) { + /// // Maybe this application needs to retry certain kinds of errors. + /// + /// # return; + /// } else { + /// eprintln!("error: {}", error); + /// process::exit(1); + /// } + /// } + /// }; + /// } + /// ``` + #[cfg(feature = "std")] + pub fn io_error_kind(&self) -> Option { + if let ErrorCode::Io(io_error) = &self.err.code { + Some(io_error.kind()) + } else { + None + } + } } /// Categorizes the cause of a `serde_json::Error`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Category { - /// The error was caused by a failure to read or write bytes on an IO + /// The error was caused by a failure to read or write bytes on an I/O /// stream. Io, @@ -134,8 +189,8 @@ pub enum Category { impl From for io::Error { /// Convert a `serde_json::Error` into an `io::Error`. /// - /// JSON syntax and data errors are turned into `InvalidData` IO errors. - /// EOF errors are turned into `UnexpectedEof` IO errors. + /// JSON syntax and data errors are turned into `InvalidData` I/O errors. + /// EOF errors are turned into `UnexpectedEof` I/O errors. /// /// ``` /// use std::io; @@ -165,8 +220,8 @@ impl From for io::Error { } else { match j.classify() { Category::Io => unreachable!(), - Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j), - Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j), + Category::Syntax | Category::Data => io::Error::new(ErrorKind::InvalidData, j), + Category::Eof => io::Error::new(ErrorKind::UnexpectedEof, j), } } } @@ -182,7 +237,7 @@ pub(crate) enum ErrorCode { /// Catchall for syntax error messages Message(Box), - /// Some IO error occurred while serializing or deserializing. + /// Some I/O error occurred while serializing or deserializing. Io(io::Error), /// EOF while parsing a list. @@ -212,6 +267,9 @@ pub(crate) enum ErrorCode { /// Expected this character to start a JSON value. ExpectedSomeValue, + /// Expected this character to be a `"`. + ExpectedDoubleQuote, + /// Invalid hex escape code. InvalidEscape, @@ -230,6 +288,12 @@ pub(crate) enum ErrorCode { /// Object key is not a string. KeyMustBeAString, + /// Contents of key were supposed to be a number. + ExpectedNumericKey, + + /// Object key is a non-finite float value. + FloatKeyMustBeFinite, + /// Lone leading surrogate in hex escape. LoneLeadingSurrogateInHexEscape, @@ -296,6 +360,7 @@ impl Display for ErrorCode { ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"), ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), ErrorCode::ExpectedSomeValue => f.write_str("expected value"), + ErrorCode::ExpectedDoubleQuote => f.write_str("expected `\"`"), ErrorCode::InvalidEscape => f.write_str("invalid escape"), ErrorCode::InvalidNumber => f.write_str("invalid number"), ErrorCode::NumberOutOfRange => f.write_str("number out of range"), @@ -304,6 +369,12 @@ impl Display for ErrorCode { f.write_str("control character (\\u0000-\\u001F) found while parsing a string") } ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), + ErrorCode::ExpectedNumericKey => { + f.write_str("invalid value: expected key to be a number in quotes") + } + ErrorCode::FloatKeyMustBeFinite => { + f.write_str("float key must be finite (got NaN or +/-inf)") + } ErrorCode::LoneLeadingSurrogateInHexEscape => { f.write_str("lone leading surrogate in hex escape") } @@ -319,7 +390,7 @@ impl serde::de::StdError for Error { #[cfg(feature = "std")] fn source(&self) -> Option<&(dyn error::Error + 'static)> { match &self.err.code { - ErrorCode::Io(err) => Some(err), + ErrorCode::Io(err) => err.source(), _ => None, } } @@ -367,11 +438,20 @@ impl de::Error for Error { #[cold] fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self { - if let de::Unexpected::Unit = unexp { - Error::custom(format_args!("invalid type: null, expected {}", exp)) - } else { - Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) - } + Error::custom(format_args!( + "invalid type: {}, expected {}", + JsonUnexpected(unexp), + exp, + )) + } + + #[cold] + fn invalid_value(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self { + Error::custom(format_args!( + "invalid value: {}, expected {}", + JsonUnexpected(unexp), + exp, + )) } } @@ -382,6 +462,22 @@ impl ser::Error for Error { } } +struct JsonUnexpected<'a>(de::Unexpected<'a>); + +impl<'a> Display for JsonUnexpected<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.0 { + de::Unexpected::Unit => formatter.write_str("null"), + de::Unexpected::Float(value) => write!( + formatter, + "floating point `{}`", + ryu::Buffer::new().format(value), + ), + unexp => Display::fmt(&unexp, formatter), + } + } +} + // Parse our own error message that looks like "{} at line {} column {}" to work // around erased-serde round-tripping the error through de::Error::custom. fn make_error(mut msg: String) -> Error { diff --git a/third_party/rust/serde_json/src/features_check/error.rs b/third_party/rust/serde_json/src/features_check/error.rs deleted file mode 100644 index 22e58235c7..0000000000 --- a/third_party/rust/serde_json/src/features_check/error.rs +++ /dev/null @@ -1 +0,0 @@ -"serde_json requires that either `std` (default) or `alloc` feature is enabled" diff --git a/third_party/rust/serde_json/src/features_check/mod.rs b/third_party/rust/serde_json/src/features_check/mod.rs deleted file mode 100644 index d12032cef8..0000000000 --- a/third_party/rust/serde_json/src/features_check/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Shows a user-friendly compiler error on incompatible selected features. - -#[allow(unused_macros)] -macro_rules! hide_from_rustfmt { - ($mod:item) => { - $mod - }; -} - -#[cfg(not(any(feature = "std", feature = "alloc")))] -hide_from_rustfmt! { - mod error; -} diff --git a/third_party/rust/serde_json/src/io/core.rs b/third_party/rust/serde_json/src/io/core.rs index 465ab8b249..54c8ddfda4 100644 --- a/third_party/rust/serde_json/src/io/core.rs +++ b/third_party/rust/serde_json/src/io/core.rs @@ -9,7 +9,7 @@ pub enum ErrorKind { Other, } -// IO errors can never occur in no-std mode. All our no-std IO implementations +// I/O errors can never occur in no-std mode. All our no-std I/O implementations // are infallible. pub struct Error; diff --git a/third_party/rust/serde_json/src/lexical/algorithm.rs b/third_party/rust/serde_json/src/lexical/algorithm.rs index a2cbf18aff..eaa5e7ebc2 100644 --- a/third_party/rust/serde_json/src/lexical/algorithm.rs +++ b/third_party/rust/serde_json/src/lexical/algorithm.rs @@ -51,7 +51,10 @@ where // Compute the product of the power, if it overflows, // prematurely return early, otherwise, if we didn't overshoot, // we can get an exact value. - let value = mantissa.checked_mul(power)?; + let value = match mantissa.checked_mul(power) { + None => return None, + Some(value) => value, + }; if value >> mantissa_size != 0 { None } else { diff --git a/third_party/rust/serde_json/src/lexical/bignum.rs b/third_party/rust/serde_json/src/lexical/bignum.rs index f9551f534f..4fa7eed6dd 100644 --- a/third_party/rust/serde_json/src/lexical/bignum.rs +++ b/third_party/rust/serde_json/src/lexical/bignum.rs @@ -3,6 +3,7 @@ //! Big integer type definition. use super::math::*; +#[allow(unused_imports)] use alloc::vec::Vec; /// Storage for a big integer type. diff --git a/third_party/rust/serde_json/src/lexical/digit.rs b/third_party/rust/serde_json/src/lexical/digit.rs index 882aa9eef2..3d150a1afe 100644 --- a/third_party/rust/serde_json/src/lexical/digit.rs +++ b/third_party/rust/serde_json/src/lexical/digit.rs @@ -11,5 +11,8 @@ pub(crate) fn to_digit(c: u8) -> Option { // Add digit to mantissa. #[inline] pub(crate) fn add_digit(value: u64, digit: u32) -> Option { - value.checked_mul(10)?.checked_add(digit as u64) + match value.checked_mul(10) { + None => None, + Some(n) => n.checked_add(digit as u64), + } } diff --git a/third_party/rust/serde_json/src/lexical/errors.rs b/third_party/rust/serde_json/src/lexical/errors.rs index cad4bd3d58..f4f41cdc5a 100644 --- a/third_party/rust/serde_json/src/lexical/errors.rs +++ b/third_party/rust/serde_json/src/lexical/errors.rs @@ -5,8 +5,7 @@ //! This estimates the error in a floating-point representation. //! //! This implementation is loosely based off the Golang implementation, -//! found here: -//! https://golang.org/src/strconv/atof.go +//! found here: use super::float::*; use super::num::*; diff --git a/third_party/rust/serde_json/src/lexical/exponent.rs b/third_party/rust/serde_json/src/lexical/exponent.rs index 6fc51977ed..5e27de893f 100644 --- a/third_party/rust/serde_json/src/lexical/exponent.rs +++ b/third_party/rust/serde_json/src/lexical/exponent.rs @@ -8,8 +8,8 @@ /// the mantissa we do not overflow for comically-long exponents. #[inline] fn into_i32(value: usize) -> i32 { - if value > i32::max_value() as usize { - i32::max_value() + if value > i32::MAX as usize { + i32::MAX } else { value as i32 } diff --git a/third_party/rust/serde_json/src/lexical/large_powers32.rs b/third_party/rust/serde_json/src/lexical/large_powers32.rs index 7991197262..eb8582f5f0 100644 --- a/third_party/rust/serde_json/src/lexical/large_powers32.rs +++ b/third_party/rust/serde_json/src/lexical/large_powers32.rs @@ -2,7 +2,7 @@ //! Precalculated large powers for 32-bit limbs. -/// Large powers (&[u32]) for base5 operations. +/// Large powers (`&[u32]`) for base5 operations. const POW5_1: [u32; 1] = [5]; const POW5_2: [u32; 1] = [25]; const POW5_3: [u32; 1] = [625]; diff --git a/third_party/rust/serde_json/src/lexical/large_powers64.rs b/third_party/rust/serde_json/src/lexical/large_powers64.rs index ee36561088..96554eac1c 100644 --- a/third_party/rust/serde_json/src/lexical/large_powers64.rs +++ b/third_party/rust/serde_json/src/lexical/large_powers64.rs @@ -2,7 +2,7 @@ //! Precalculated large powers for 64-bit limbs. -/// Large powers (&[u64]) for base5 operations. +/// Large powers (`&[u64]`) for base5 operations. const POW5_1: [u64; 1] = [5]; const POW5_2: [u64; 1] = [25]; const POW5_3: [u64; 1] = [625]; diff --git a/third_party/rust/serde_json/src/lexical/math.rs b/third_party/rust/serde_json/src/lexical/math.rs index 37cc1d24ad..d7122bffaf 100644 --- a/third_party/rust/serde_json/src/lexical/math.rs +++ b/third_party/rust/serde_json/src/lexical/math.rs @@ -336,7 +336,7 @@ mod small { pub fn imul(x: &mut Vec, y: Limb) { // Multiply iteratively over all elements, adding the carry each time. let mut carry: Limb = 0; - for xi in x.iter_mut() { + for xi in &mut *x { carry = scalar::imul(xi, y, carry); } @@ -482,7 +482,7 @@ mod small { let rshift = bits - n; let lshift = n; let mut prev: Limb = 0; - for xi in x.iter_mut() { + for xi in &mut *x { let tmp = *xi; *xi <<= lshift; *xi |= prev >> rshift; diff --git a/third_party/rust/serde_json/src/lexical/num.rs b/third_party/rust/serde_json/src/lexical/num.rs index e47e003419..75eee01b81 100644 --- a/third_party/rust/serde_json/src/lexical/num.rs +++ b/third_party/rust/serde_json/src/lexical/num.rs @@ -223,7 +223,7 @@ pub trait Float: Number { const NEGATIVE_INFINITY_BITS: Self::Unsigned; /// Size of the significand (mantissa) without hidden bit. const MANTISSA_SIZE: i32; - /// Bias of the exponet + /// Bias of the exponent const EXPONENT_BIAS: i32; /// Exponent portion of a denormal float. const DENORMAL_EXPONENT: i32; @@ -248,7 +248,6 @@ pub trait Float: Number { fn from_bits(u: Self::Unsigned) -> Self; fn to_bits(self) -> Self::Unsigned; fn is_sign_positive(self) -> bool; - fn is_sign_negative(self) -> bool; /// Returns true if the float is a denormal. #[inline] @@ -368,11 +367,6 @@ impl Float for f32 { fn is_sign_positive(self) -> bool { f32::is_sign_positive(self) } - - #[inline] - fn is_sign_negative(self) -> bool { - f32::is_sign_negative(self) - } } impl Float for f64 { @@ -432,9 +426,4 @@ impl Float for f64 { fn is_sign_positive(self) -> bool { f64::is_sign_positive(self) } - - #[inline] - fn is_sign_negative(self) -> bool { - f64::is_sign_negative(self) - } } diff --git a/third_party/rust/serde_json/src/lexical/rounding.rs b/third_party/rust/serde_json/src/lexical/rounding.rs index 6ec1292aa5..6344875227 100644 --- a/third_party/rust/serde_json/src/lexical/rounding.rs +++ b/third_party/rust/serde_json/src/lexical/rounding.rs @@ -25,7 +25,7 @@ pub(crate) fn lower_n_mask(n: u64) -> u64 { debug_assert!(n <= bits, "lower_n_mask() overflow in shl."); if n == bits { - u64::max_value() + u64::MAX } else { (1 << n) - 1 } diff --git a/third_party/rust/serde_json/src/lib.rs b/third_party/rust/serde_json/src/lib.rs index 48d0fe2191..eabd169f53 100644 --- a/third_party/rust/serde_json/src/lib.rs +++ b/third_party/rust/serde_json/src/lib.rs @@ -55,10 +55,9 @@ //! ``` //! //! A string of JSON data can be parsed into a `serde_json::Value` by the -//! [`serde_json::from_str`][from_str] function. There is also -//! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and -//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or -//! a TCP stream. +//! [`serde_json::from_str`][from_str] function. There is also [`from_slice`] +//! for parsing from a byte slice `&[u8]` and [`from_reader`] for parsing from +//! any `io::Read` like a File or a TCP stream. //! //! ``` //! use serde_json::{Result, Value}; @@ -300,7 +299,7 @@ //! [macro]: crate::json //! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core -#![doc(html_root_url = "https://docs.rs/serde_json/1.0.93")] +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.116")] // Ignored clippy lints #![allow( clippy::collapsible_else_if, @@ -315,18 +314,13 @@ clippy::match_single_binding, clippy::needless_doctest_main, clippy::needless_late_init, - // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8366 - clippy::ptr_arg, clippy::return_self_not_must_use, clippy::transmute_ptr_to_ptr, - clippy::unnecessary_wraps, - // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 - clippy::unnested_or_patterns, + clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133 + clippy::unnecessary_wraps )] // Ignored clippy_pedantic lints #![allow( - // buggy - clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285 // Deserializer::from_str, into_iter clippy::should_implement_trait, // integer and float ser/de requires these sorts of casts @@ -338,6 +332,7 @@ clippy::enum_glob_use, clippy::if_not_else, clippy::integer_division, + clippy::let_underscore_untyped, clippy::map_err_ignore, clippy::match_same_arms, clippy::similar_names, @@ -361,14 +356,25 @@ clippy::missing_errors_doc, clippy::must_use_candidate, )] +// Restrictions +#![deny(clippy::question_mark_used)] #![allow(non_upper_case_globals)] #![deny(missing_docs)] -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] +#[cfg(not(any(feature = "std", feature = "alloc")))] +compile_error! { + "serde_json requires that either `std` (default) or `alloc` feature is enabled" +} + extern crate alloc; #[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[doc(inline)] pub use crate::de::from_reader; #[doc(inline)] @@ -378,6 +384,7 @@ pub use crate::error::{Error, Result}; #[doc(inline)] pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[doc(inline)] pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; #[doc(inline)] @@ -407,8 +414,6 @@ pub mod ser; mod ser; pub mod value; -mod features_check; - mod io; #[cfg(feature = "std")] mod iter; diff --git a/third_party/rust/serde_json/src/macros.rs b/third_party/rust/serde_json/src/macros.rs index 5287998b46..e8c6cd2ca4 100644 --- a/third_party/rust/serde_json/src/macros.rs +++ b/third_party/rust/serde_json/src/macros.rs @@ -10,7 +10,8 @@ /// "features": [ /// "serde", /// "json" -/// ] +/// ], +/// "homepage": null /// } /// }); /// ``` diff --git a/third_party/rust/serde_json/src/map.rs b/third_party/rust/serde_json/src/map.rs index 3e8a3814c9..520cd6cf53 100644 --- a/third_party/rust/serde_json/src/map.rs +++ b/third_party/rust/serde_json/src/map.rs @@ -11,7 +11,7 @@ use alloc::string::String; use core::borrow::Borrow; use core::fmt::{self, Debug}; use core::hash::Hash; -use core::iter::{FromIterator, FusedIterator}; +use core::iter::FusedIterator; #[cfg(feature = "preserve_order")] use core::mem; use core::ops; @@ -20,7 +20,7 @@ use serde::de; #[cfg(not(feature = "preserve_order"))] use alloc::collections::{btree_map, BTreeMap}; #[cfg(feature = "preserve_order")] -use indexmap::{self, IndexMap}; +use indexmap::IndexMap; /// Represents a JSON key/value type. pub struct Map { @@ -106,7 +106,6 @@ impl Map { /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. #[inline] - #[cfg(any(feature = "preserve_order", not(no_btreemap_get_key_value)))] pub fn get_key_value(&self, key: &Q) -> Option<(&String, &Value)> where String: Borrow, @@ -131,6 +130,12 @@ impl Map { /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. + /// + /// If serde_json's "preserve_order" is enabled, `.remove(key)` is + /// equivalent to [`.swap_remove(key)`][Self::swap_remove], replacing this + /// entry's position with the last element. If you need to preserve the + /// relative order of the keys in the map, use + /// [`.shift_remove(key)`][Self::shift_remove] instead. #[inline] pub fn remove(&mut self, key: &Q) -> Option where @@ -138,7 +143,7 @@ impl Map { Q: ?Sized + Ord + Eq + Hash, { #[cfg(feature = "preserve_order")] - return self.map.swap_remove(key); + return self.swap_remove(key); #[cfg(not(feature = "preserve_order"))] return self.map.remove(key); } @@ -148,49 +153,94 @@ impl Map { /// /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. + /// + /// If serde_json's "preserve_order" is enabled, `.remove_entry(key)` is + /// equivalent to [`.swap_remove_entry(key)`][Self::swap_remove_entry], + /// replacing this entry's position with the last element. If you need to + /// preserve the relative order of the keys in the map, use + /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead. + #[inline] pub fn remove_entry(&mut self, key: &Q) -> Option<(String, Value)> where String: Borrow, Q: ?Sized + Ord + Eq + Hash, { - #[cfg(any(feature = "preserve_order", not(no_btreemap_remove_entry)))] + #[cfg(feature = "preserve_order")] + return self.swap_remove_entry(key); + #[cfg(not(feature = "preserve_order"))] return self.map.remove_entry(key); - #[cfg(all( - not(feature = "preserve_order"), - no_btreemap_remove_entry, - not(no_btreemap_get_key_value), - ))] - { - let (key, _value) = self.map.get_key_value(key)?; - let key = key.clone(); - let value = self.map.remove::(&key)?; - Some((key, value)) - } - #[cfg(all( - not(feature = "preserve_order"), - no_btreemap_remove_entry, - no_btreemap_get_key_value, - ))] - { - use core::ops::{Bound, RangeBounds}; - - struct Key<'a, Q: ?Sized>(&'a Q); - - impl<'a, Q: ?Sized> RangeBounds for Key<'a, Q> { - fn start_bound(&self) -> Bound<&Q> { - Bound::Included(self.0) - } - fn end_bound(&self) -> Bound<&Q> { - Bound::Included(self.0) - } - } + } - let mut range = self.map.range(Key(key)); - let (key, _value) = range.next()?; - let key = key.clone(); - let value = self.map.remove::(&key)?; - Some((key, value)) - } + /// Removes and returns the value corresponding to the key from the map. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.swap_remove(key) + } + + /// Remove and return the key-value pair. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.swap_remove_entry(key) + } + + /// Removes and returns the value corresponding to the key from the map. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.shift_remove(key) + } + + /// Remove and return the key-value pair. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.shift_remove_entry(key) } /// Moves all elements from other into self, leaving other empty. @@ -276,7 +326,6 @@ impl Map { /// /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` /// returns `false`. - #[cfg(not(no_btreemap_retain))] #[inline] pub fn retain(&mut self, f: F) where diff --git a/third_party/rust/serde_json/src/number.rs b/third_party/rust/serde_json/src/number.rs index 21a76411cc..878a3dcb20 100644 --- a/third_party/rust/serde_json/src/number.rs +++ b/third_party/rust/serde_json/src/number.rs @@ -82,7 +82,7 @@ impl Number { /// ``` /// # use serde_json::json; /// # - /// let big = i64::max_value() as u64 + 10; + /// let big = i64::MAX as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// /// assert!(v["a"].is_i64()); @@ -97,7 +97,7 @@ impl Number { pub fn is_i64(&self) -> bool { #[cfg(not(feature = "arbitrary_precision"))] match self.n { - N::PosInt(v) => v <= i64::max_value() as u64, + N::PosInt(v) => v <= i64::MAX as u64, N::NegInt(_) => true, N::Float(_) => false, } @@ -177,7 +177,7 @@ impl Number { /// ``` /// # use serde_json::json; /// # - /// let big = i64::max_value() as u64 + 10; + /// let big = i64::MAX as u64 + 10; /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); /// /// assert_eq!(v["a"].as_i64(), Some(64)); @@ -189,7 +189,7 @@ impl Number { #[cfg(not(feature = "arbitrary_precision"))] match self.n { N::PosInt(n) => { - if n <= i64::max_value() as u64 { + if n <= i64::MAX as u64 { Some(n as i64) } else { None @@ -279,6 +279,62 @@ impl Number { } } + /// Returns the exact original JSON representation that this Number was + /// parsed from. + /// + /// For numbers constructed not via parsing, such as by `From`, returns + /// the JSON representation that serde\_json would serialize for this + /// number. + /// + /// ``` + /// # use serde_json::Number; + /// for value in [ + /// "7", + /// "12.34", + /// "34e-56789", + /// "0.0123456789000000012345678900000001234567890000123456789", + /// "343412345678910111213141516171819202122232425262728293034", + /// "-343412345678910111213141516171819202122232425262728293031", + /// ] { + /// let number: Number = serde_json::from_str(value).unwrap(); + /// assert_eq!(number.as_str(), value); + /// } + /// ``` + #[cfg(feature = "arbitrary_precision")] + #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary_precision")))] + pub fn as_str(&self) -> &str { + &self.n + } + + pub(crate) fn as_f32(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n as f32), + N::NegInt(n) => Some(n as f32), + N::Float(n) => Some(n as f32), + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse::().ok().filter(|float| float.is_finite()) + } + + pub(crate) fn from_f32(f: f32) -> Option { + if f.is_finite() { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f as f64) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format_finite(f).to_owned() + } + }; + Some(Number { n }) + } else { + None + } + } + #[cfg(feature = "arbitrary_precision")] /// Not public API. Only tests use this. #[doc(hidden)] @@ -332,8 +388,8 @@ impl Serialize for Number { { use serde::ser::SerializeStruct; - let mut s = serializer.serialize_struct(TOKEN, 1)?; - s.serialize_field(TOKEN, &self.n)?; + let mut s = tri!(serializer.serialize_struct(TOKEN, 1)); + tri!(s.serialize_field(TOKEN, &self.n)); s.end() } } @@ -377,11 +433,11 @@ impl<'de> Deserialize<'de> for Number { where V: de::MapAccess<'de>, { - let value = visitor.next_key::()?; + let value = tri!(visitor.next_key::()); if value.is_none() { return Err(de::Error::invalid_type(Unexpected::Map, &self)); } - let v: NumberFromString = visitor.next_value()?; + let v: NumberFromString = tri!(visitor.next_value()); Ok(v.value) } } @@ -420,7 +476,7 @@ impl<'de> de::Deserialize<'de> for NumberKey { } } - deserializer.deserialize_identifier(FieldVisitor)?; + tri!(deserializer.deserialize_identifier(FieldVisitor)); Ok(NumberKey) } } @@ -523,7 +579,7 @@ macro_rules! deserialize_number { where V: de::Visitor<'de>, { - visitor.$visit(self.n.parse().map_err(|_| invalid_number())?) + visitor.$visit(tri!(self.n.parse().map_err(|_| invalid_number()))) } }; } diff --git a/third_party/rust/serde_json/src/raw.rs b/third_party/rust/serde_json/src/raw.rs index 6aa4ffcb61..22d14441ec 100644 --- a/third_party/rust/serde_json/src/raw.rs +++ b/third_party/rust/serde_json/src/raw.rs @@ -112,8 +112,8 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; /// raw_value: Box, /// } /// ``` -#[cfg_attr(not(doc), repr(transparent))] #[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))] +#[repr(transparent)] pub struct RawValue { json: str, } @@ -177,11 +177,9 @@ impl RawValue { /// - the input has no leading or trailing whitespace, and /// - the input has capacity equal to its length. pub fn from_string(json: String) -> Result, Error> { - { - let borrowed = crate::from_str::<&Self>(&json)?; - if borrowed.json.len() < json.len() { - return Ok(borrowed.to_owned()); - } + let borrowed = tri!(crate::from_str::<&Self>(&json)); + if borrowed.json.len() < json.len() { + return Ok(borrowed.to_owned()); } Ok(Self::from_owned(json.into_boxed_str())) } @@ -287,7 +285,7 @@ pub fn to_raw_value(value: &T) -> Result, Error> where T: ?Sized + Serialize, { - let json_string = crate::to_string(value)?; + let json_string = tri!(crate::to_string(value)); Ok(RawValue::from_owned(json_string.into_boxed_str())) } @@ -298,8 +296,8 @@ impl Serialize for RawValue { where S: Serializer, { - let mut s = serializer.serialize_struct(TOKEN, 1)?; - s.serialize_field(TOKEN, &self.json)?; + let mut s = tri!(serializer.serialize_struct(TOKEN, 1)); + tri!(s.serialize_field(TOKEN, &self.json)); s.end() } } @@ -322,7 +320,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { where V: MapAccess<'de>, { - let value = visitor.next_key::()?; + let value = tri!(visitor.next_key::()); if value.is_none() { return Err(de::Error::invalid_type(Unexpected::Map, &self)); } @@ -352,7 +350,7 @@ impl<'de> Deserialize<'de> for Box { where V: MapAccess<'de>, { - let value = visitor.next_key::()?; + let value = tri!(visitor.next_key::()); if value.is_none() { return Err(de::Error::invalid_type(Unexpected::Map, &self)); } @@ -392,7 +390,7 @@ impl<'de> Deserialize<'de> for RawKey { } } - deserializer.deserialize_identifier(FieldVisitor)?; + tri!(deserializer.deserialize_identifier(FieldVisitor)); Ok(RawKey) } } @@ -529,3 +527,251 @@ impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> { seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap())) } } + +impl<'de> IntoDeserializer<'de, Error> for &'de RawValue { + type Deserializer = &'de RawValue; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> Deserializer<'de> for &'de RawValue { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_any(visitor) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_bool(visitor) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i8(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i16(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i32(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i64(visitor) + } + + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i128(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u8(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u16(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u32(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u64(visitor) + } + + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u128(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_f32(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_f64(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_char(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_str(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_string(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_bytes(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_byte_buf(visitor) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_option(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_unit(visitor) + } + + fn deserialize_unit_struct(self, name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_unit_struct(name, visitor) + } + + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_newtype_struct(name, visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_seq(visitor) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_tuple_struct(name, len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_map(visitor) + } + + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_enum(name, variants, visitor) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_identifier(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_ignored_any(visitor) + } +} diff --git a/third_party/rust/serde_json/src/read.rs b/third_party/rust/serde_json/src/read.rs index fc3a3ca748..a426911c7d 100644 --- a/third_party/rust/serde_json/src/read.rs +++ b/third_party/rust/serde_json/src/read.rs @@ -14,11 +14,13 @@ use crate::iter::LineColIterator; use crate::raw::BorrowedRawDeserializer; #[cfg(all(feature = "raw_value", feature = "std"))] use crate::raw::OwnedRawDeserializer; +#[cfg(all(feature = "raw_value", feature = "std"))] +use alloc::string::String; #[cfg(feature = "raw_value")] use serde::de::Visitor; /// Trait used by the deserializer for iterating over input. This is manually -/// "specialized" for iterating over &[u8]. Once feature(specialization) is +/// "specialized" for iterating over `&[u8]`. Once feature(specialization) is /// stable we can use actual specialization. /// /// This trait is sealed and cannot be implemented for types outside of @@ -81,7 +83,7 @@ pub trait Read<'de>: private::Sealed { #[doc(hidden)] fn ignore_str(&mut self) -> Result<()>; - /// Assumes the previous byte was a hex escape sequnce ('\u') in a string. + /// Assumes the previous byte was a hex escape sequence ('\u') in a string. /// Parses next hexadecimal sequence. #[doc(hidden)] fn decode_hex_escape(&mut self) -> Result; diff --git a/third_party/rust/serde_json/src/ser.rs b/third_party/rust/serde_json/src/ser.rs index 80c2deb0c1..3742e0bef4 100644 --- a/third_party/rust/serde_json/src/ser.rs +++ b/third_party/rust/serde_json/src/ser.rs @@ -189,12 +189,9 @@ where #[inline] fn serialize_bytes(self, value: &[u8]) -> Result<()> { - use serde::ser::SerializeSeq; - let mut seq = tri!(self.serialize_seq(Some(value.len()))); - for byte in value { - tri!(seq.serialize_element(byte)); - } - seq.end() + self.formatter + .write_byte_array(&mut self.writer, value) + .map_err(Error::io) } #[inline] @@ -439,17 +436,15 @@ where .formatter .begin_string(&mut self.writer) .map_err(Error::io)); - { - let mut adapter = Adapter { - writer: &mut self.writer, - formatter: &mut self.formatter, - error: None, - }; - match write!(adapter, "{}", value) { - Ok(()) => debug_assert!(adapter.error.is_none()), - Err(fmt::Error) => { - return Err(Error::io(adapter.error.expect("there should be an error"))); - } + let mut adapter = Adapter { + writer: &mut self.writer, + formatter: &mut self.formatter, + error: None, + }; + match write!(adapter, "{}", value) { + Ok(()) => debug_assert!(adapter.error.is_none()), + Err(fmt::Error) => { + return Err(Error::io(adapter.error.expect("there should be an error"))); } } self.formatter @@ -789,6 +784,10 @@ fn key_must_be_a_string() -> Error { Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) } +fn float_key_must_be_finite() -> Error { + Error::syntax(ErrorCode::FloatKeyMustBeFinite, 0, 0) +} + impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> where W: io::Write, @@ -828,8 +827,21 @@ where type SerializeStruct = Impossible<(), Error>; type SerializeStructVariant = Impossible<(), Error>; - fn serialize_bool(self, _value: bool) -> Result<()> { - Err(key_must_be_a_string()) + fn serialize_bool(self, value: bool) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_bool(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) } fn serialize_i8(self, value: i8) -> Result<()> { @@ -1002,12 +1014,46 @@ where .map_err(Error::io) } - fn serialize_f32(self, _value: f32) -> Result<()> { - Err(key_must_be_a_string()) + fn serialize_f32(self, value: f32) -> Result<()> { + if !value.is_finite() { + return Err(float_key_must_be_finite()); + } + + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_f32(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) } - fn serialize_f64(self, _value: f64) -> Result<()> { - Err(key_must_be_a_string()) + fn serialize_f64(self, value: f64) -> Result<()> { + if !value.is_finite() { + return Err(float_key_must_be_finite()); + } + + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_f64(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) } fn serialize_char(self, value: char) -> Result<()> { @@ -1043,11 +1089,11 @@ where Err(key_must_be_a_string()) } - fn serialize_some(self, _value: &T) -> Result<()> + fn serialize_some(self, value: &T) -> Result<()> where T: ?Sized + Serialize, { - Err(key_must_be_a_string()) + value.serialize(self) } fn serialize_seq(self, _len: Option) -> Result { @@ -1734,6 +1780,24 @@ pub trait Formatter { writer.write_all(s) } + /// Writes the representation of a byte array. Formatters can choose whether + /// to represent bytes as a JSON array of integers (the default), or some + /// JSON string encoding like hex or base64. + fn write_byte_array(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()> + where + W: ?Sized + io::Write, + { + tri!(self.begin_array(writer)); + let mut first = true; + for byte in value { + tri!(self.begin_array_value(writer, first)); + tri!(self.write_u8(writer, *byte)); + tri!(self.end_array_value(writer)); + first = false; + } + self.end_array(writer) + } + /// Called before every array. Writes a `[` to the specified /// writer. #[inline] @@ -2062,7 +2126,9 @@ static ESCAPE: [u8; 256] = [ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F ]; -/// Serialize the given data structure as JSON into the IO stream. +/// Serialize the given data structure as JSON into the I/O stream. +/// +/// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. /// /// # Errors /// @@ -2079,9 +2145,11 @@ where value.serialize(&mut ser) } -/// Serialize the given data structure as pretty-printed JSON into the IO +/// Serialize the given data structure as pretty-printed JSON into the I/O /// stream. /// +/// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. +/// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to diff --git a/third_party/rust/serde_json/src/value/de.rs b/third_party/rust/serde_json/src/value/de.rs index 9c266d08ae..936725635f 100644 --- a/third_party/rust/serde_json/src/value/de.rs +++ b/third_party/rust/serde_json/src/value/de.rs @@ -1,4 +1,4 @@ -use crate::error::Error; +use crate::error::{Error, ErrorCode}; use crate::map::Map; use crate::number::Number; use crate::value::Value; @@ -106,15 +106,15 @@ impl<'de> Deserialize<'de> for Value { where V: MapAccess<'de>, { - match visitor.next_key_seed(KeyClassifier)? { + match tri!(visitor.next_key_seed(KeyClassifier)) { #[cfg(feature = "arbitrary_precision")] Some(KeyClass::Number) => { - let number: NumberFromString = visitor.next_value()?; + let number: NumberFromString = tri!(visitor.next_value()); Ok(Value::Number(number.value)) } #[cfg(feature = "raw_value")] Some(KeyClass::RawValue) => { - let value = visitor.next_value_seed(crate::raw::BoxedFromString)?; + let value = tri!(visitor.next_value_seed(crate::raw::BoxedFromString)); crate::from_str(value.get()).map_err(de::Error::custom) } Some(KeyClass::Map(first_key)) => { @@ -219,6 +219,8 @@ impl<'de> serde::Deserializer<'de> for Value { Value::Number(n) => n.deserialize_any(visitor), #[cfg(any(feature = "std", feature = "alloc"))] Value::String(v) => visitor.visit_string(v), + #[cfg(not(any(feature = "std", feature = "alloc")))] + Value::String(_) => unreachable!(), Value::Array(v) => visit_array(v, visitor), Value::Object(v) => visit_object(v, visitor), } @@ -482,6 +484,14 @@ impl<'de> IntoDeserializer<'de, Error> for Value { } } +impl<'de> IntoDeserializer<'de, Error> for &'de Value { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + struct VariantDeserializer { value: Option, } @@ -1120,18 +1130,30 @@ struct MapKeyDeserializer<'de> { key: Cow<'de, str>, } -macro_rules! deserialize_integer_key { - ($method:ident => $visit:ident) => { +macro_rules! deserialize_numeric_key { + ($method:ident) => { + deserialize_numeric_key!($method, deserialize_number); + }; + + ($method:ident, $using:ident) => { fn $method(self, visitor: V) -> Result where V: Visitor<'de>, { - match (self.key.parse(), self.key) { - (Ok(integer), _) => visitor.$visit(integer), - (Err(_), Cow::Borrowed(s)) => visitor.visit_borrowed_str(s), - #[cfg(any(feature = "std", feature = "alloc"))] - (Err(_), Cow::Owned(s)) => visitor.visit_string(s), + let mut de = crate::Deserializer::from_str(&self.key); + + match tri!(de.peek()) { + Some(b'0'..=b'9' | b'-') => {} + _ => return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)), + } + + let number = tri!(de.$using(visitor)); + + if tri!(de.peek()).is_some() { + return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)); } + + Ok(number) } }; } @@ -1146,16 +1168,38 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) } - deserialize_integer_key!(deserialize_i8 => visit_i8); - deserialize_integer_key!(deserialize_i16 => visit_i16); - deserialize_integer_key!(deserialize_i32 => visit_i32); - deserialize_integer_key!(deserialize_i64 => visit_i64); - deserialize_integer_key!(deserialize_i128 => visit_i128); - deserialize_integer_key!(deserialize_u8 => visit_u8); - deserialize_integer_key!(deserialize_u16 => visit_u16); - deserialize_integer_key!(deserialize_u32 => visit_u32); - deserialize_integer_key!(deserialize_u64 => visit_u64); - deserialize_integer_key!(deserialize_u128 => visit_u128); + deserialize_numeric_key!(deserialize_i8); + deserialize_numeric_key!(deserialize_i16); + deserialize_numeric_key!(deserialize_i32); + deserialize_numeric_key!(deserialize_i64); + deserialize_numeric_key!(deserialize_u8); + deserialize_numeric_key!(deserialize_u16); + deserialize_numeric_key!(deserialize_u32); + deserialize_numeric_key!(deserialize_u64); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_numeric_key!(deserialize_f32); + deserialize_numeric_key!(deserialize_f64); + + #[cfg(feature = "float_roundtrip")] + deserialize_numeric_key!(deserialize_f32, do_deserialize_f32); + deserialize_numeric_key!(deserialize_i128, do_deserialize_i128); + deserialize_numeric_key!(deserialize_u128, do_deserialize_u128); + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + if self.key == "true" { + visitor.visit_bool(true) + } else if self.key == "false" { + visitor.visit_bool(false) + } else { + Err(serde::de::Error::invalid_type( + Unexpected::Str(&self.key), + &visitor, + )) + } + } #[inline] fn deserialize_option(self, visitor: V) -> Result @@ -1193,8 +1237,8 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { } forward_to_deserialize_any! { - bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple - tuple_struct map struct identifier ignored_any + char str string bytes byte_buf unit unit_struct seq tuple tuple_struct + map struct identifier ignored_any } } @@ -1297,6 +1341,8 @@ impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> { Cow::Borrowed(string) => visitor.visit_borrowed_str(string), #[cfg(any(feature = "std", feature = "alloc"))] Cow::Owned(string) => visitor.visit_string(string), + #[cfg(not(any(feature = "std", feature = "alloc")))] + Cow::Owned(_) => unreachable!(), } } @@ -1327,7 +1373,7 @@ impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { where T: de::DeserializeSeed<'de>, { - let value = seed.deserialize(self)?; + let value = tri!(seed.deserialize(self)); Ok((value, UnitOnly)) } } diff --git a/third_party/rust/serde_json/src/value/from.rs b/third_party/rust/serde_json/src/value/from.rs index c5a6a3960b..ed1e3338b0 100644 --- a/third_party/rust/serde_json/src/value/from.rs +++ b/third_party/rust/serde_json/src/value/from.rs @@ -4,7 +4,6 @@ use crate::number::Number; use alloc::borrow::Cow; use alloc::string::{String, ToString}; use alloc::vec::Vec; -use core::iter::FromIterator; macro_rules! from_integer { ($($ty:ident)*) => { @@ -29,7 +28,8 @@ from_integer! { } impl From for Value { - /// Convert 32-bit floating point number to `Value` + /// Convert 32-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. /// /// # Examples /// @@ -40,12 +40,13 @@ impl From for Value { /// let x: Value = f.into(); /// ``` fn from(f: f32) -> Self { - From::from(f as f64) + Number::from_f32(f).map_or(Value::Null, Value::Number) } } impl From for Value { - /// Convert 64-bit floating point number to `Value` + /// Convert 64-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. /// /// # Examples /// @@ -61,7 +62,7 @@ impl From for Value { } impl From for Value { - /// Convert boolean to `Value` + /// Convert boolean to `Value::Bool`. /// /// # Examples /// @@ -77,7 +78,7 @@ impl From for Value { } impl From for Value { - /// Convert `String` to `Value` + /// Convert `String` to `Value::String`. /// /// # Examples /// @@ -92,8 +93,8 @@ impl From for Value { } } -impl<'a> From<&'a str> for Value { - /// Convert string slice to `Value` +impl From<&str> for Value { + /// Convert string slice to `Value::String`. /// /// # Examples /// @@ -109,7 +110,7 @@ impl<'a> From<&'a str> for Value { } impl<'a> From> for Value { - /// Convert copy-on-write string to `Value` + /// Convert copy-on-write string to `Value::String`. /// /// # Examples /// @@ -134,7 +135,7 @@ impl<'a> From> for Value { } impl From for Value { - /// Convert `Number` to `Value` + /// Convert `Number` to `Value::Number`. /// /// # Examples /// @@ -150,7 +151,7 @@ impl From for Value { } impl From> for Value { - /// Convert map (with string keys) to `Value` + /// Convert map (with string keys) to `Value::Object`. /// /// # Examples /// @@ -167,7 +168,7 @@ impl From> for Value { } impl> From> for Value { - /// Convert a `Vec` to `Value` + /// Convert a `Vec` to `Value::Array`. /// /// # Examples /// @@ -182,8 +183,8 @@ impl> From> for Value { } } -impl<'a, T: Clone + Into> From<&'a [T]> for Value { - /// Convert a slice to `Value` +impl> From<&[T]> for Value { + /// Convert a slice to `Value::Array`. /// /// # Examples /// @@ -193,13 +194,13 @@ impl<'a, T: Clone + Into> From<&'a [T]> for Value { /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; /// let x: Value = v.into(); /// ``` - fn from(f: &'a [T]) -> Self { + fn from(f: &[T]) -> Self { Value::Array(f.iter().cloned().map(Into::into).collect()) } } impl> FromIterator for Value { - /// Convert an iteratable type to a `Value` + /// Create a `Value::Array` by collecting an iterator of array elements. /// /// # Examples /// @@ -229,7 +230,7 @@ impl> FromIterator for Value { } impl, V: Into> FromIterator<(K, V)> for Value { - /// Convert an iteratable type to a `Value` + /// Create a `Value::Object` by collecting an iterator of key-value pairs. /// /// # Examples /// @@ -249,7 +250,7 @@ impl, V: Into> FromIterator<(K, V)> for Value { } impl From<()> for Value { - /// Convert `()` to `Value` + /// Convert `()` to `Value::Null`. /// /// # Examples /// diff --git a/third_party/rust/serde_json/src/value/index.rs b/third_party/rust/serde_json/src/value/index.rs index c74042b75a..891ca8ef73 100644 --- a/third_party/rust/serde_json/src/value/index.rs +++ b/third_party/rust/serde_json/src/value/index.rs @@ -116,7 +116,7 @@ impl Index for String { } } -impl<'a, T> Index for &'a T +impl Index for &T where T: ?Sized + Index, { diff --git a/third_party/rust/serde_json/src/value/mod.rs b/third_party/rust/serde_json/src/value/mod.rs index 470b6b24da..b3f51ea0db 100644 --- a/third_party/rust/serde_json/src/value/mod.rs +++ b/third_party/rust/serde_json/src/value/mod.rs @@ -106,6 +106,7 @@ pub use crate::map::Map; pub use crate::number::Number; #[cfg(feature = "raw_value")] +#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))] pub use crate::raw::{to_raw_value, RawValue}; /// Represents any valid JSON value. @@ -182,11 +183,11 @@ impl Debug for Value { Value::Number(number) => Debug::fmt(number, formatter), Value::String(string) => write!(formatter, "String({:?})", string), Value::Array(vec) => { - formatter.write_str("Array ")?; + tri!(formatter.write_str("Array ")); Debug::fmt(vec, formatter) } Value::Object(map) => { - formatter.write_str("Object ")?; + tri!(formatter.write_str("Object ")); Debug::fmt(map, formatter) } } @@ -514,6 +515,28 @@ impl Value { } } + /// If the `Value` is a Number, returns the associated [`Number`]. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::{json, Number}; + /// # + /// let v = json!({ "a": 1, "b": 2.2, "c": -3, "d": "4" }); + /// + /// assert_eq!(v["a"].as_number(), Some(&Number::from(1u64))); + /// assert_eq!(v["b"].as_number(), Some(&Number::from_f64(2.2).unwrap())); + /// assert_eq!(v["c"].as_number(), Some(&Number::from(-3i64))); + /// + /// // The string `"4"` is not a number. + /// assert_eq!(v["d"].as_number(), None); + /// ``` + pub fn as_number(&self) -> Option<&Number> { + match self { + Value::Number(number) => Some(number), + _ => None, + } + } + /// Returns true if the `Value` is an integer between `i64::MIN` and /// `i64::MAX`. /// @@ -889,7 +912,6 @@ mod ser; /// ``` /// use serde::Serialize; /// use serde_json::json; -/// /// use std::error::Error; /// /// #[derive(Serialize)] @@ -898,7 +920,7 @@ mod ser; /// location: String, /// } /// -/// fn compare_json_values() -> Result<(), Box> { +/// fn compare_json_values() -> Result<(), Box> { /// let u = User { /// fingerprint: "0xF9BA143B95FF6D82".to_owned(), /// location: "Menlo Park, CA".to_owned(), diff --git a/third_party/rust/serde_json/src/value/partial_eq.rs b/third_party/rust/serde_json/src/value/partial_eq.rs index b4ef84c4f3..46c1dbc33b 100644 --- a/third_party/rust/serde_json/src/value/partial_eq.rs +++ b/third_party/rust/serde_json/src/value/partial_eq.rs @@ -9,6 +9,13 @@ fn eq_u64(value: &Value, other: u64) -> bool { value.as_u64().map_or(false, |i| i == other) } +fn eq_f32(value: &Value, other: f32) -> bool { + match value { + Value::Number(n) => n.as_f32().map_or(false, |i| i == other), + _ => false, + } +} + fn eq_f64(value: &Value, other: f64) -> bool { value.as_f64().map_or(false, |i| i == other) } @@ -27,7 +34,7 @@ impl PartialEq for Value { } } -impl<'a> PartialEq<&'a str> for Value { +impl PartialEq<&str> for Value { fn eq(&self, other: &&str) -> bool { eq_str(self, *other) } @@ -39,7 +46,7 @@ impl PartialEq for str { } } -impl<'a> PartialEq for &'a str { +impl PartialEq for &str { fn eq(&self, other: &Value) -> bool { eq_str(other, *self) } @@ -90,6 +97,7 @@ macro_rules! partialeq_numeric { partialeq_numeric! { eq_i64[i8 i16 i32 i64 isize] eq_u64[u8 u16 u32 u64 usize] - eq_f64[f32 f64] + eq_f32[f32] + eq_f64[f64] eq_bool[bool] } diff --git a/third_party/rust/serde_json/src/value/ser.rs b/third_party/rust/serde_json/src/value/ser.rs index a29814e92a..e869ae160f 100644 --- a/third_party/rust/serde_json/src/value/ser.rs +++ b/third_party/rust/serde_json/src/value/ser.rs @@ -1,12 +1,9 @@ use crate::error::{Error, ErrorCode, Result}; use crate::map::Map; -use crate::number::Number; use crate::value::{to_value, Value}; use alloc::borrow::ToOwned; use alloc::string::{String, ToString}; use alloc::vec::Vec; -#[cfg(not(feature = "arbitrary_precision"))] -use core::convert::TryFrom; use core::fmt::Display; use core::result; use serde::ser::{Impossible, Serialize}; @@ -32,6 +29,8 @@ impl Serialize for Value { } map.end() } + #[cfg(not(any(feature = "std", feature = "alloc")))] + Value::Object(_) => unreachable!(), } } } @@ -149,13 +148,13 @@ impl serde::Serializer for Serializer { } #[inline] - fn serialize_f32(self, value: f32) -> Result { - self.serialize_f64(value as f64) + fn serialize_f32(self, float: f32) -> Result { + Ok(Value::from(float)) } #[inline] - fn serialize_f64(self, value: f64) -> Result { - Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + fn serialize_f64(self, float: f64) -> Result { + Ok(Value::from(float)) } #[inline] @@ -452,6 +451,10 @@ fn key_must_be_a_string() -> Error { Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) } +fn float_key_must_be_finite() -> Error { + Error::syntax(ErrorCode::FloatKeyMustBeFinite, 0, 0) +} + impl serde::Serializer for MapKeySerializer { type Ok = String; type Error = Error; @@ -482,8 +485,8 @@ impl serde::Serializer for MapKeySerializer { value.serialize(self) } - fn serialize_bool(self, _value: bool) -> Result { - Err(key_must_be_a_string()) + fn serialize_bool(self, value: bool) -> Result { + Ok(value.to_string()) } fn serialize_i8(self, value: i8) -> Result { @@ -518,12 +521,20 @@ impl serde::Serializer for MapKeySerializer { Ok(value.to_string()) } - fn serialize_f32(self, _value: f32) -> Result { - Err(key_must_be_a_string()) + fn serialize_f32(self, value: f32) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } } - fn serialize_f64(self, _value: f64) -> Result { - Err(key_must_be_a_string()) + fn serialize_f64(self, value: f64) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } } #[inline] @@ -641,7 +652,7 @@ impl serde::ser::SerializeStruct for SerializeMap { #[cfg(feature = "arbitrary_precision")] SerializeMap::Number { out_value } => { if key == crate::number::TOKEN { - *out_value = Some(value.serialize(NumberValueEmitter)?); + *out_value = Some(tri!(value.serialize(NumberValueEmitter))); Ok(()) } else { Err(invalid_number()) @@ -650,7 +661,7 @@ impl serde::ser::SerializeStruct for SerializeMap { #[cfg(feature = "raw_value")] SerializeMap::RawValue { out_value } => { if key == crate::raw::TOKEN { - *out_value = Some(value.serialize(RawValueEmitter)?); + *out_value = Some(tri!(value.serialize(RawValueEmitter))); Ok(()) } else { Err(invalid_raw_value()) -- cgit v1.2.3