diff options
Diffstat (limited to 'src/value')
-rw-r--r-- | src/value/de.rs | 90 | ||||
-rw-r--r-- | src/value/from.rs | 37 | ||||
-rw-r--r-- | src/value/index.rs | 2 | ||||
-rw-r--r-- | src/value/mod.rs | 30 | ||||
-rw-r--r-- | src/value/partial_eq.rs | 14 | ||||
-rw-r--r-- | src/value/ser.rs | 39 |
6 files changed, 65 insertions, 147 deletions
diff --git a/src/value/de.rs b/src/value/de.rs index 1e8b5ac..9c266d0 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -1,4 +1,4 @@ -use crate::error::{Error, ErrorCode}; +use crate::error::Error; 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 tri!(visitor.next_key_seed(KeyClassifier)) { + match visitor.next_key_seed(KeyClassifier)? { #[cfg(feature = "arbitrary_precision")] Some(KeyClass::Number) => { - let number: NumberFromString = tri!(visitor.next_value()); + let number: NumberFromString = visitor.next_value()?; Ok(Value::Number(number.value)) } #[cfg(feature = "raw_value")] Some(KeyClass::RawValue) => { - let value = tri!(visitor.next_value_seed(crate::raw::BoxedFromString)); + let value = visitor.next_value_seed(crate::raw::BoxedFromString)?; crate::from_str(value.get()).map_err(de::Error::custom) } Some(KeyClass::Map(first_key)) => { @@ -482,14 +482,6 @@ 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>, } @@ -1128,30 +1120,18 @@ struct MapKeyDeserializer<'de> { key: Cow<'de, str>, } -macro_rules! deserialize_numeric_key { - ($method:ident) => { - deserialize_numeric_key!($method, deserialize_number); - }; - - ($method:ident, $using:ident) => { +macro_rules! deserialize_integer_key { + ($method:ident => $visit:ident) => { fn $method<V>(self, visitor: V) -> Result<V::Value, Error> where V: Visitor<'de>, { - 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)); + 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), } - - Ok(number) } }; } @@ -1166,38 +1146,16 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) } - 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, - )) - } - } + 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); #[inline] fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> @@ -1235,8 +1193,8 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { } forward_to_deserialize_any! { - char str string bytes byte_buf unit unit_struct seq tuple tuple_struct - map struct identifier ignored_any + bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple + tuple_struct map struct identifier ignored_any } } @@ -1369,7 +1327,7 @@ impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { where T: de::DeserializeSeed<'de>, { - let value = tri!(seed.deserialize(self)); + let value = seed.deserialize(self)?; Ok((value, UnitOnly)) } } diff --git a/src/value/from.rs b/src/value/from.rs index ed1e333..c5a6a39 100644 --- a/src/value/from.rs +++ b/src/value/from.rs @@ -4,6 +4,7 @@ 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)*) => { @@ -28,8 +29,7 @@ from_integer! { } impl From<f32> for Value { - /// Convert 32-bit floating point number to `Value::Number`, or - /// `Value::Null` if infinite or NaN. + /// Convert 32-bit floating point number to `Value` /// /// # Examples /// @@ -40,13 +40,12 @@ impl From<f32> for Value { /// let x: Value = f.into(); /// ``` fn from(f: f32) -> Self { - Number::from_f32(f).map_or(Value::Null, Value::Number) + From::from(f as f64) } } impl From<f64> for Value { - /// Convert 64-bit floating point number to `Value::Number`, or - /// `Value::Null` if infinite or NaN. + /// Convert 64-bit floating point number to `Value` /// /// # Examples /// @@ -62,7 +61,7 @@ impl From<f64> for Value { } impl From<bool> for Value { - /// Convert boolean to `Value::Bool`. + /// Convert boolean to `Value` /// /// # Examples /// @@ -78,7 +77,7 @@ impl From<bool> for Value { } impl From<String> for Value { - /// Convert `String` to `Value::String`. + /// Convert `String` to `Value` /// /// # Examples /// @@ -93,8 +92,8 @@ impl From<String> for Value { } } -impl From<&str> for Value { - /// Convert string slice to `Value::String`. +impl<'a> From<&'a str> for Value { + /// Convert string slice to `Value` /// /// # Examples /// @@ -110,7 +109,7 @@ impl From<&str> for Value { } impl<'a> From<Cow<'a, str>> for Value { - /// Convert copy-on-write string to `Value::String`. + /// Convert copy-on-write string to `Value` /// /// # Examples /// @@ -135,7 +134,7 @@ impl<'a> From<Cow<'a, str>> for Value { } impl From<Number> for Value { - /// Convert `Number` to `Value::Number`. + /// Convert `Number` to `Value` /// /// # Examples /// @@ -151,7 +150,7 @@ impl From<Number> for Value { } impl From<Map<String, Value>> for Value { - /// Convert map (with string keys) to `Value::Object`. + /// Convert map (with string keys) to `Value` /// /// # Examples /// @@ -168,7 +167,7 @@ impl From<Map<String, Value>> for Value { } impl<T: Into<Value>> From<Vec<T>> for Value { - /// Convert a `Vec` to `Value::Array`. + /// Convert a `Vec` to `Value` /// /// # Examples /// @@ -183,8 +182,8 @@ impl<T: Into<Value>> From<Vec<T>> for Value { } } -impl<T: Clone + Into<Value>> From<&[T]> for Value { - /// Convert a slice to `Value::Array`. +impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value { + /// Convert a slice to `Value` /// /// # Examples /// @@ -194,13 +193,13 @@ impl<T: Clone + Into<Value>> From<&[T]> for Value { /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; /// let x: Value = v.into(); /// ``` - fn from(f: &[T]) -> Self { + fn from(f: &'a [T]) -> Self { Value::Array(f.iter().cloned().map(Into::into).collect()) } } impl<T: Into<Value>> FromIterator<T> for Value { - /// Create a `Value::Array` by collecting an iterator of array elements. + /// Convert an iteratable type to a `Value` /// /// # Examples /// @@ -230,7 +229,7 @@ impl<T: Into<Value>> FromIterator<T> for Value { } impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value { - /// Create a `Value::Object` by collecting an iterator of key-value pairs. + /// Convert an iteratable type to a `Value` /// /// # Examples /// @@ -250,7 +249,7 @@ impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value { } impl From<()> for Value { - /// Convert `()` to `Value::Null`. + /// Convert `()` to `Value` /// /// # Examples /// diff --git a/src/value/index.rs b/src/value/index.rs index 891ca8e..c74042b 100644 --- a/src/value/index.rs +++ b/src/value/index.rs @@ -116,7 +116,7 @@ impl Index for String { } } -impl<T> Index for &T +impl<'a, T> Index for &'a T where T: ?Sized + Index, { diff --git a/src/value/mod.rs b/src/value/mod.rs index b3f51ea..470b6b2 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -106,7 +106,6 @@ 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. @@ -183,11 +182,11 @@ impl Debug for Value { Value::Number(number) => Debug::fmt(number, formatter), Value::String(string) => write!(formatter, "String({:?})", string), Value::Array(vec) => { - tri!(formatter.write_str("Array ")); + formatter.write_str("Array ")?; Debug::fmt(vec, formatter) } Value::Object(map) => { - tri!(formatter.write_str("Object ")); + formatter.write_str("Object ")?; Debug::fmt(map, formatter) } } @@ -515,28 +514,6 @@ 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`. /// @@ -912,6 +889,7 @@ mod ser; /// ``` /// use serde::Serialize; /// use serde_json::json; +/// /// use std::error::Error; /// /// #[derive(Serialize)] @@ -920,7 +898,7 @@ mod ser; /// location: String, /// } /// -/// fn compare_json_values() -> Result<(), Box<dyn Error>> { +/// fn compare_json_values() -> Result<(), Box<Error>> { /// let u = User { /// fingerprint: "0xF9BA143B95FF6D82".to_owned(), /// location: "Menlo Park, CA".to_owned(), diff --git a/src/value/partial_eq.rs b/src/value/partial_eq.rs index 46c1dbc..b4ef84c 100644 --- a/src/value/partial_eq.rs +++ b/src/value/partial_eq.rs @@ -9,13 +9,6 @@ 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) } @@ -34,7 +27,7 @@ impl PartialEq<str> for Value { } } -impl PartialEq<&str> for Value { +impl<'a> PartialEq<&'a str> for Value { fn eq(&self, other: &&str) -> bool { eq_str(self, *other) } @@ -46,7 +39,7 @@ impl PartialEq<Value> for str { } } -impl PartialEq<Value> for &str { +impl<'a> PartialEq<Value> for &'a str { fn eq(&self, other: &Value) -> bool { eq_str(other, *self) } @@ -97,7 +90,6 @@ macro_rules! partialeq_numeric { partialeq_numeric! { eq_i64[i8 i16 i32 i64 isize] eq_u64[u8 u16 u32 u64 usize] - eq_f32[f32] - eq_f64[f64] + eq_f64[f32 f64] eq_bool[bool] } diff --git a/src/value/ser.rs b/src/value/ser.rs index 835fa90..a29814e 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -1,9 +1,12 @@ 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}; @@ -146,13 +149,13 @@ impl serde::Serializer for Serializer { } #[inline] - fn serialize_f32(self, float: f32) -> Result<Value> { - Ok(Value::from(float)) + fn serialize_f32(self, value: f32) -> Result<Value> { + self.serialize_f64(value as f64) } #[inline] - fn serialize_f64(self, float: f64) -> Result<Value> { - Ok(Value::from(float)) + fn serialize_f64(self, value: f64) -> Result<Value> { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) } #[inline] @@ -449,10 +452,6 @@ 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; @@ -483,8 +482,8 @@ impl serde::Serializer for MapKeySerializer { value.serialize(self) } - fn serialize_bool(self, value: bool) -> Result<String> { - Ok(value.to_string()) + fn serialize_bool(self, _value: bool) -> Result<String> { + Err(key_must_be_a_string()) } fn serialize_i8(self, value: i8) -> Result<String> { @@ -519,20 +518,12 @@ impl serde::Serializer for MapKeySerializer { Ok(value.to_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_f32(self, _value: f32) -> 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()) - } + fn serialize_f64(self, _value: f64) -> Result<String> { + Err(key_must_be_a_string()) } #[inline] @@ -650,7 +641,7 @@ impl serde::ser::SerializeStruct for SerializeMap { #[cfg(feature = "arbitrary_precision")] SerializeMap::Number { out_value } => { if key == crate::number::TOKEN { - *out_value = Some(tri!(value.serialize(NumberValueEmitter))); + *out_value = Some(value.serialize(NumberValueEmitter)?); Ok(()) } else { Err(invalid_number()) @@ -659,7 +650,7 @@ impl serde::ser::SerializeStruct for SerializeMap { #[cfg(feature = "raw_value")] SerializeMap::RawValue { out_value } => { if key == crate::raw::TOKEN { - *out_value = Some(tri!(value.serialize(RawValueEmitter))); + *out_value = Some(value.serialize(RawValueEmitter)?); Ok(()) } else { Err(invalid_raw_value()) |