mirror of
https://github.com/serde-rs/json.git
synced 2025-10-02 07:21:29 +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.
|
/// 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>
|
impl<'de> serde::Deserializer<'de> for Map<String, Value> {
|
||||||
where
|
type Error = Error;
|
||||||
V: Visitor<'de>,
|
|
||||||
{
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
let len = object.len();
|
where
|
||||||
let mut deserializer = MapDeserializer::new(object);
|
V: Visitor<'de>,
|
||||||
let map = tri!(visitor.visit_map(&mut deserializer));
|
{
|
||||||
let remaining = deserializer.iter.len();
|
let len = self.len();
|
||||||
if remaining == 0 {
|
let mut deserializer = MapDeserializer::new(self);
|
||||||
Ok(map)
|
let map = tri!(visitor.visit_map(&mut deserializer));
|
||||||
} else {
|
let remaining = deserializer.iter.len();
|
||||||
Err(serde::de::Error::invalid_length(
|
if remaining == 0 {
|
||||||
len,
|
Ok(map)
|
||||||
&"fewer elements in 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")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||||
Value::String(_) => unreachable!(),
|
Value::String(_) => unreachable!(),
|
||||||
Value::Array(v) => visit_array(v, visitor),
|
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]
|
#[inline]
|
||||||
fn deserialize_enum<V>(
|
fn deserialize_enum<V>(
|
||||||
self,
|
self,
|
||||||
_name: &str,
|
name: &'static str,
|
||||||
_variants: &'static [&'static str],
|
variants: &'static [&'static str],
|
||||||
visitor: V,
|
visitor: V,
|
||||||
) -> Result<V::Value, Error>
|
) -> Result<V::Value, Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let (variant, value) = match self {
|
match self {
|
||||||
Value::Object(value) => {
|
Value::Object(value) => value.deserialize_enum(name, variants, visitor),
|
||||||
let mut iter = value.into_iter();
|
Value::String(variant) => visitor.visit_enum(EnumDeserializer {
|
||||||
let (variant, value) = match iter.next() {
|
variant,
|
||||||
Some(v) => v,
|
value: None,
|
||||||
None => {
|
}),
|
||||||
return Err(serde::de::Error::invalid_value(
|
other => Err(serde::de::Error::invalid_type(
|
||||||
Unexpected::Map,
|
other.unexpected(),
|
||||||
&"map with a single key",
|
&"string or map",
|
||||||
));
|
)),
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// 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 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -436,7 +467,7 @@ impl<'de> serde::Deserializer<'de> for Value {
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Value::Object(v) => visit_object(v, visitor),
|
Value::Object(v) => v.deserialize_any(visitor),
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -452,7 +483,7 @@ impl<'de> serde::Deserializer<'de> for Value {
|
|||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => visit_array(v, visitor),
|
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)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,8 +597,10 @@ impl<'de> VariantAccess<'de> for VariantDeserializer {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
use serde::de::Deserializer;
|
||||||
|
|
||||||
match self.value {
|
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(
|
Some(other) => Err(serde::de::Error::invalid_type(
|
||||||
other.unexpected(),
|
other.unexpected(),
|
||||||
&"struct variant",
|
&"struct variant",
|
||||||
@ -708,21 +741,71 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_object_ref<'de, V>(object: &'de Map<String, Value>, visitor: V) -> Result<V::Value, Error>
|
impl<'de> serde::Deserializer<'de> for &'de Map<String, Value> {
|
||||||
where
|
type Error = Error;
|
||||||
V: Visitor<'de>,
|
|
||||||
{
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
let len = object.len();
|
where
|
||||||
let mut deserializer = MapRefDeserializer::new(object);
|
V: Visitor<'de>,
|
||||||
let map = tri!(visitor.visit_map(&mut deserializer));
|
{
|
||||||
let remaining = deserializer.iter.len();
|
let len = self.len();
|
||||||
if remaining == 0 {
|
let mut deserializer = MapRefDeserializer::new(self);
|
||||||
Ok(map)
|
let map = tri!(visitor.visit_map(&mut deserializer));
|
||||||
} else {
|
let remaining = deserializer.iter.len();
|
||||||
Err(serde::de::Error::invalid_length(
|
if remaining == 0 {
|
||||||
len,
|
Ok(map)
|
||||||
&"fewer elements in 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::Number(n) => n.deserialize_any(visitor),
|
||||||
Value::String(v) => visitor.visit_borrowed_str(v),
|
Value::String(v) => visitor.visit_borrowed_str(v),
|
||||||
Value::Array(v) => visit_array_ref(v, visitor),
|
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>(
|
fn deserialize_enum<V>(
|
||||||
self,
|
self,
|
||||||
_name: &str,
|
name: &'static str,
|
||||||
_variants: &'static [&'static str],
|
variants: &'static [&'static str],
|
||||||
visitor: V,
|
visitor: V,
|
||||||
) -> Result<V::Value, Error>
|
) -> Result<V::Value, Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let (variant, value) = match self {
|
match self {
|
||||||
Value::Object(value) => {
|
Value::Object(value) => value.deserialize_enum(name, variants, visitor),
|
||||||
let mut iter = value.into_iter();
|
Value::String(variant) => visitor.visit_enum(EnumRefDeserializer {
|
||||||
let (variant, value) = match iter.next() {
|
variant,
|
||||||
Some(v) => v,
|
value: None,
|
||||||
None => {
|
}),
|
||||||
return Err(serde::de::Error::invalid_value(
|
other => Err(serde::de::Error::invalid_type(
|
||||||
Unexpected::Map,
|
other.unexpected(),
|
||||||
&"map with a single key",
|
&"string or map",
|
||||||
));
|
)),
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// 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 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -933,7 +996,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Value::Object(v) => visit_object_ref(v, visitor),
|
Value::Object(v) => v.deserialize_any(visitor),
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -949,7 +1012,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
|
|||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => visit_array_ref(v, visitor),
|
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)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1046,8 +1109,10 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
use serde::de::Deserializer;
|
||||||
|
|
||||||
match self.value {
|
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(
|
Some(other) => Err(serde::de::Error::invalid_type(
|
||||||
other.unexpected(),
|
other.unexpected(),
|
||||||
&"struct variant",
|
&"struct variant",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user