mirror of
https://github.com/serde-rs/json.git
synced 2025-09-30 22:41:51 +00:00
Merge pull request #1135 from swlynch99/map-deserializer
Implement `Deserializer` for `Map<String, Value>` and `&Map<String, Value>`
This commit is contained in:
commit
b4954a9561
16
src/map.rs
16
src/map.rs
@ -589,6 +589,22 @@ macro_rules! delegate_iterator {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::IntoDeserializer<'de, crate::Error> for Map<String, Value> {
|
||||
type Deserializer = Self;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::IntoDeserializer<'de, crate::Error> for &'de Map<String, Value> {
|
||||
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.
|
||||
|
273
src/value/de.rs
273
src/value/de.rs
@ -203,21 +203,72 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_object<'de, V>(object: Map<String, Value>, visitor: V) -> Result<V::Value, Error>
|
||||
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<String, Value> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
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<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
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<V>(
|
||||
self,
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
name: &'static str,
|
||||
variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
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<String, Value>, visitor: V) -> Result<V::Value, Error>
|
||||
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<String, Value> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
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<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
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<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
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<V>(
|
||||
self,
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
name: &'static str,
|
||||
variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user