diff --git a/src/map.rs b/src/map.rs index eb5297e43..d8e700c1c 100644 --- a/src/map.rs +++ b/src/map.rs @@ -589,6 +589,22 @@ macro_rules! delegate_iterator { } } +impl<'de> de::IntoDeserializer<'de, crate::Error> for Map { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> de::IntoDeserializer<'de, crate::Error> for &'de Map { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + ////////////////////////////////////////////////////////////////////////////// /// A view into a single entry in a map, which may either be vacant or occupied. diff --git a/src/value/de.rs b/src/value/de.rs index 45891f033..b494b981b 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -203,21 +203,72 @@ where } } -fn visit_object<'de, V>(object: Map, visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = object.len(); - let mut deserializer = MapDeserializer::new(object); - let map = tri!(visitor.visit_map(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(map) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in map", - )) +impl<'de> serde::Deserializer<'de> for Map { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.len(); + let mut deserializer = MapDeserializer::new(self); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let mut iter = self.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + + visitor.visit_enum(EnumDeserializer { + variant, + value: Some(value), + }) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier } } @@ -238,7 +289,7 @@ impl<'de> serde::Deserializer<'de> for Value { #[cfg(not(any(feature = "std", feature = "alloc")))] Value::String(_) => unreachable!(), Value::Array(v) => visit_array(v, visitor), - Value::Object(v) => visit_object(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), } } @@ -269,44 +320,24 @@ impl<'de> serde::Deserializer<'de> for Value { #[inline] fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &'static str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { - let (variant, value) = match self { - Value::Object(value) => { - let mut iter = value.into_iter(); - let (variant, value) = match iter.next() { - Some(v) => v, - None => { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - (variant, Some(value)) - } - Value::String(variant) => (variant, None), - other => { - return Err(serde::de::Error::invalid_type( - other.unexpected(), - &"string or map", - )); - } - }; - - visitor.visit_enum(EnumDeserializer { variant, value }) + match self { + Value::Object(value) => value.deserialize_enum(name, variants, visitor), + Value::String(variant) => visitor.visit_enum(EnumDeserializer { + variant, + value: None, + }), + other => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )), + } } #[inline] @@ -436,7 +467,7 @@ impl<'de> serde::Deserializer<'de> for Value { V: Visitor<'de>, { match self { - Value::Object(v) => visit_object(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), _ => Err(self.invalid_type(&visitor)), } } @@ -452,7 +483,7 @@ impl<'de> serde::Deserializer<'de> for Value { { match self { Value::Array(v) => visit_array(v, visitor), - Value::Object(v) => visit_object(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), _ => Err(self.invalid_type(&visitor)), } } @@ -566,8 +597,10 @@ impl<'de> VariantAccess<'de> for VariantDeserializer { where V: Visitor<'de>, { + use serde::de::Deserializer; + match self.value { - Some(Value::Object(v)) => visit_object(v, visitor), + Some(Value::Object(v)) => v.deserialize_any(visitor), Some(other) => Err(serde::de::Error::invalid_type( other.unexpected(), &"struct variant", @@ -708,21 +741,71 @@ where } } -fn visit_object_ref<'de, V>(object: &'de Map, visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = object.len(); - let mut deserializer = MapRefDeserializer::new(object); - let map = tri!(visitor.visit_map(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(map) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in map", - )) +impl<'de> serde::Deserializer<'de> for &'de Map { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.len(); + let mut deserializer = MapRefDeserializer::new(self); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let mut iter = self.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + + visitor.visit_enum(EnumRefDeserializer { + variant, + value: Some(value), + }) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier } } @@ -739,7 +822,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value { Value::Number(n) => n.deserialize_any(visitor), Value::String(v) => visitor.visit_borrowed_str(v), Value::Array(v) => visit_array_ref(v, visitor), - Value::Object(v) => visit_object_ref(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), } } @@ -768,44 +851,24 @@ impl<'de> serde::Deserializer<'de> for &'de Value { fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &'static str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { - let (variant, value) = match self { - Value::Object(value) => { - let mut iter = value.into_iter(); - let (variant, value) = match iter.next() { - Some(v) => v, - None => { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - (variant, Some(value)) - } - Value::String(variant) => (variant, None), - other => { - return Err(serde::de::Error::invalid_type( - other.unexpected(), - &"string or map", - )); - } - }; - - visitor.visit_enum(EnumRefDeserializer { variant, value }) + match self { + Value::Object(value) => value.deserialize_enum(name, variants, visitor), + Value::String(variant) => visitor.visit_enum(EnumRefDeserializer { + variant, + value: None, + }), + other => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )), + } } #[inline] @@ -933,7 +996,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value { V: Visitor<'de>, { match self { - Value::Object(v) => visit_object_ref(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), _ => Err(self.invalid_type(&visitor)), } } @@ -949,7 +1012,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value { { match self { Value::Array(v) => visit_array_ref(v, visitor), - Value::Object(v) => visit_object_ref(v, visitor), + Value::Object(v) => v.deserialize_any(visitor), _ => Err(self.invalid_type(&visitor)), } } @@ -1046,8 +1109,10 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { where V: Visitor<'de>, { + use serde::de::Deserializer; + match self.value { - Some(Value::Object(v)) => visit_object_ref(v, visitor), + Some(Value::Object(v)) => v.deserialize_any(visitor), Some(other) => Err(serde::de::Error::invalid_type( other.unexpected(), &"struct variant",