aboutsummaryrefslogtreecommitdiff
path: root/src/value
diff options
context:
space:
mode:
Diffstat (limited to 'src/value')
-rw-r--r--src/value/de.rs90
-rw-r--r--src/value/from.rs37
-rw-r--r--src/value/index.rs2
-rw-r--r--src/value/mod.rs30
-rw-r--r--src/value/partial_eq.rs14
-rw-r--r--src/value/ser.rs39
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())