summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_json/src/value
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/serde_json/src/value')
-rw-r--r--third_party/rust/serde_json/src/value/de.rs94
-rw-r--r--third_party/rust/serde_json/src/value/from.rs37
-rw-r--r--third_party/rust/serde_json/src/value/index.rs2
-rw-r--r--third_party/rust/serde_json/src/value/mod.rs30
-rw-r--r--third_party/rust/serde_json/src/value/partial_eq.rs14
-rw-r--r--third_party/rust/serde_json/src/value/ser.rs41
6 files changed, 153 insertions, 65 deletions
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<Value>,
}
@@ -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<V>(self, visitor: V) -> Result<V::Value, Error>
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<V>(self, visitor: V) -> Result<V::Value, Error>
+ 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<V>(self, visitor: V) -> Result<V::Value, Error>
@@ -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<f32> 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<f32> 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<f64> 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<f64> for Value {
}
impl From<bool> for Value {
- /// Convert boolean to `Value`
+ /// Convert boolean to `Value::Bool`.
///
/// # Examples
///
@@ -77,7 +78,7 @@ impl From<bool> for Value {
}
impl From<String> for Value {
- /// Convert `String` to `Value`
+ /// Convert `String` to `Value::String`.
///
/// # Examples
///
@@ -92,8 +93,8 @@ impl From<String> 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<Cow<'a, str>> 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<Cow<'a, str>> for Value {
}
impl From<Number> for Value {
- /// Convert `Number` to `Value`
+ /// Convert `Number` to `Value::Number`.
///
/// # Examples
///
@@ -150,7 +151,7 @@ impl From<Number> for Value {
}
impl From<Map<String, Value>> for Value {
- /// Convert map (with string keys) to `Value`
+ /// Convert map (with string keys) to `Value::Object`.
///
/// # Examples
///
@@ -167,7 +168,7 @@ impl From<Map<String, Value>> for Value {
}
impl<T: Into<Value>> From<Vec<T>> for Value {
- /// Convert a `Vec` to `Value`
+ /// Convert a `Vec` to `Value::Array`.
///
/// # Examples
///
@@ -182,8 +183,8 @@ impl<T: Into<Value>> From<Vec<T>> for Value {
}
}
-impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
- /// Convert a slice to `Value`
+impl<T: Clone + Into<Value>> From<&[T]> for Value {
+ /// Convert a slice to `Value::Array`.
///
/// # Examples
///
@@ -193,13 +194,13 @@ impl<'a, T: Clone + Into<Value>> 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<T: Into<Value>> FromIterator<T> 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<T: Into<Value>> FromIterator<T> for Value {
}
impl<K: Into<String>, V: Into<Value>> 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<K: Into<String>, V: Into<Value>> 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<T> 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<Error>> {
+/// fn compare_json_values() -> Result<(), Box<dyn Error>> {
/// 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<str> 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<Value> for str {
}
}
-impl<'a> PartialEq<Value> for &'a str {
+impl PartialEq<Value> 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<Value> {
- self.serialize_f64(value as f64)
+ fn serialize_f32(self, float: f32) -> Result<Value> {
+ Ok(Value::from(float))
}
#[inline]
- fn serialize_f64(self, value: f64) -> Result<Value> {
- Ok(Number::from_f64(value).map_or(Value::Null, Value::Number))
+ fn serialize_f64(self, float: f64) -> Result<Value> {
+ 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<String> {
- Err(key_must_be_a_string())
+ fn serialize_bool(self, value: bool) -> Result<String> {
+ Ok(value.to_string())
}
fn serialize_i8(self, value: i8) -> Result<String> {
@@ -518,12 +521,20 @@ impl serde::Serializer for MapKeySerializer {
Ok(value.to_string())
}
- fn serialize_f32(self, _value: f32) -> Result<String> {
- Err(key_must_be_a_string())
+ fn serialize_f32(self, value: f32) -> Result<String> {
+ 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<String> {
- Err(key_must_be_a_string())
+ fn serialize_f64(self, value: f64) -> Result<String> {
+ 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())