aboutsummaryrefslogtreecommitdiff
path: root/src/value/de.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/value/de.rs')
-rw-r--r--src/value/de.rs90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/value/de.rs b/src/value/de.rs
index 9c266d0..1e8b5ac 100644
--- a/src/value/de.rs
+++ b/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)) => {
@@ -482,6 +482,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 +1128,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 +1166,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 +1235,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
}
}
@@ -1327,7 +1369,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))
}
}