Skip to content

Commit b4954a9

Browse files
authored
Merge pull request #1135 from swlynch99/map-deserializer
Implement `Deserializer` for `Map<String, Value>` and `&Map<String, Value>`
2 parents 2825e15 + c2540b0 commit b4954a9

File tree

2 files changed

+185
-104
lines changed

2 files changed

+185
-104
lines changed

src/map.rs

+16
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,22 @@ macro_rules! delegate_iterator {
589589
}
590590
}
591591

592+
impl<'de> de::IntoDeserializer<'de, crate::Error> for Map<String, Value> {
593+
type Deserializer = Self;
594+
595+
fn into_deserializer(self) -> Self::Deserializer {
596+
self
597+
}
598+
}
599+
600+
impl<'de> de::IntoDeserializer<'de, crate::Error> for &'de Map<String, Value> {
601+
type Deserializer = Self;
602+
603+
fn into_deserializer(self) -> Self::Deserializer {
604+
self
605+
}
606+
}
607+
592608
//////////////////////////////////////////////////////////////////////////////
593609

594610
/// A view into a single entry in a map, which may either be vacant or occupied.

src/value/de.rs

+169-104
Original file line numberDiff line numberDiff line change
@@ -203,21 +203,72 @@ where
203203
}
204204
}
205205

206-
fn visit_object<'de, V>(object: Map<String, Value>, visitor: V) -> Result<V::Value, Error>
207-
where
208-
V: Visitor<'de>,
209-
{
210-
let len = object.len();
211-
let mut deserializer = MapDeserializer::new(object);
212-
let map = tri!(visitor.visit_map(&mut deserializer));
213-
let remaining = deserializer.iter.len();
214-
if remaining == 0 {
215-
Ok(map)
216-
} else {
217-
Err(serde::de::Error::invalid_length(
218-
len,
219-
&"fewer elements in map",
220-
))
206+
impl<'de> serde::Deserializer<'de> for Map<String, Value> {
207+
type Error = Error;
208+
209+
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
210+
where
211+
V: Visitor<'de>,
212+
{
213+
let len = self.len();
214+
let mut deserializer = MapDeserializer::new(self);
215+
let map = tri!(visitor.visit_map(&mut deserializer));
216+
let remaining = deserializer.iter.len();
217+
if remaining == 0 {
218+
Ok(map)
219+
} else {
220+
Err(serde::de::Error::invalid_length(
221+
len,
222+
&"fewer elements in map",
223+
))
224+
}
225+
}
226+
227+
fn deserialize_enum<V>(
228+
self,
229+
_name: &'static str,
230+
_variants: &'static [&'static str],
231+
visitor: V,
232+
) -> Result<V::Value, Self::Error>
233+
where
234+
V: Visitor<'de>,
235+
{
236+
let mut iter = self.into_iter();
237+
let (variant, value) = match iter.next() {
238+
Some(v) => v,
239+
None => {
240+
return Err(serde::de::Error::invalid_value(
241+
Unexpected::Map,
242+
&"map with a single key",
243+
));
244+
}
245+
};
246+
// enums are encoded in json as maps with a single key:value pair
247+
if iter.next().is_some() {
248+
return Err(serde::de::Error::invalid_value(
249+
Unexpected::Map,
250+
&"map with a single key",
251+
));
252+
}
253+
254+
visitor.visit_enum(EnumDeserializer {
255+
variant,
256+
value: Some(value),
257+
})
258+
}
259+
260+
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
261+
where
262+
V: Visitor<'de>,
263+
{
264+
drop(self);
265+
visitor.visit_unit()
266+
}
267+
268+
forward_to_deserialize_any! {
269+
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
270+
bytes byte_buf option unit unit_struct newtype_struct seq tuple
271+
tuple_struct map struct identifier
221272
}
222273
}
223274

@@ -238,7 +289,7 @@ impl<'de> serde::Deserializer<'de> for Value {
238289
#[cfg(not(any(feature = "std", feature = "alloc")))]
239290
Value::String(_) => unreachable!(),
240291
Value::Array(v) => visit_array(v, visitor),
241-
Value::Object(v) => visit_object(v, visitor),
292+
Value::Object(v) => v.deserialize_any(visitor),
242293
}
243294
}
244295

@@ -269,44 +320,24 @@ impl<'de> serde::Deserializer<'de> for Value {
269320
#[inline]
270321
fn deserialize_enum<V>(
271322
self,
272-
_name: &str,
273-
_variants: &'static [&'static str],
323+
name: &'static str,
324+
variants: &'static [&'static str],
274325
visitor: V,
275326
) -> Result<V::Value, Error>
276327
where
277328
V: Visitor<'de>,
278329
{
279-
let (variant, value) = match self {
280-
Value::Object(value) => {
281-
let mut iter = value.into_iter();
282-
let (variant, value) = match iter.next() {
283-
Some(v) => v,
284-
None => {
285-
return Err(serde::de::Error::invalid_value(
286-
Unexpected::Map,
287-
&"map with a single key",
288-
));
289-
}
290-
};
291-
// enums are encoded in json as maps with a single key:value pair
292-
if iter.next().is_some() {
293-
return Err(serde::de::Error::invalid_value(
294-
Unexpected::Map,
295-
&"map with a single key",
296-
));
297-
}
298-
(variant, Some(value))
299-
}
300-
Value::String(variant) => (variant, None),
301-
other => {
302-
return Err(serde::de::Error::invalid_type(
303-
other.unexpected(),
304-
&"string or map",
305-
));
306-
}
307-
};
308-
309-
visitor.visit_enum(EnumDeserializer { variant, value })
330+
match self {
331+
Value::Object(value) => value.deserialize_enum(name, variants, visitor),
332+
Value::String(variant) => visitor.visit_enum(EnumDeserializer {
333+
variant,
334+
value: None,
335+
}),
336+
other => Err(serde::de::Error::invalid_type(
337+
other.unexpected(),
338+
&"string or map",
339+
)),
340+
}
310341
}
311342

312343
#[inline]
@@ -436,7 +467,7 @@ impl<'de> serde::Deserializer<'de> for Value {
436467
V: Visitor<'de>,
437468
{
438469
match self {
439-
Value::Object(v) => visit_object(v, visitor),
470+
Value::Object(v) => v.deserialize_any(visitor),
440471
_ => Err(self.invalid_type(&visitor)),
441472
}
442473
}
@@ -452,7 +483,7 @@ impl<'de> serde::Deserializer<'de> for Value {
452483
{
453484
match self {
454485
Value::Array(v) => visit_array(v, visitor),
455-
Value::Object(v) => visit_object(v, visitor),
486+
Value::Object(v) => v.deserialize_any(visitor),
456487
_ => Err(self.invalid_type(&visitor)),
457488
}
458489
}
@@ -566,8 +597,10 @@ impl<'de> VariantAccess<'de> for VariantDeserializer {
566597
where
567598
V: Visitor<'de>,
568599
{
600+
use serde::de::Deserializer;
601+
569602
match self.value {
570-
Some(Value::Object(v)) => visit_object(v, visitor),
603+
Some(Value::Object(v)) => v.deserialize_any(visitor),
571604
Some(other) => Err(serde::de::Error::invalid_type(
572605
other.unexpected(),
573606
&"struct variant",
@@ -708,21 +741,71 @@ where
708741
}
709742
}
710743

711-
fn visit_object_ref<'de, V>(object: &'de Map<String, Value>, visitor: V) -> Result<V::Value, Error>
712-
where
713-
V: Visitor<'de>,
714-
{
715-
let len = object.len();
716-
let mut deserializer = MapRefDeserializer::new(object);
717-
let map = tri!(visitor.visit_map(&mut deserializer));
718-
let remaining = deserializer.iter.len();
719-
if remaining == 0 {
720-
Ok(map)
721-
} else {
722-
Err(serde::de::Error::invalid_length(
723-
len,
724-
&"fewer elements in map",
725-
))
744+
impl<'de> serde::Deserializer<'de> for &'de Map<String, Value> {
745+
type Error = Error;
746+
747+
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
748+
where
749+
V: Visitor<'de>,
750+
{
751+
let len = self.len();
752+
let mut deserializer = MapRefDeserializer::new(self);
753+
let map = tri!(visitor.visit_map(&mut deserializer));
754+
let remaining = deserializer.iter.len();
755+
if remaining == 0 {
756+
Ok(map)
757+
} else {
758+
Err(serde::de::Error::invalid_length(
759+
len,
760+
&"fewer elements in map",
761+
))
762+
}
763+
}
764+
765+
fn deserialize_enum<V>(
766+
self,
767+
_name: &'static str,
768+
_variants: &'static [&'static str],
769+
visitor: V,
770+
) -> Result<V::Value, Self::Error>
771+
where
772+
V: Visitor<'de>,
773+
{
774+
let mut iter = self.into_iter();
775+
let (variant, value) = match iter.next() {
776+
Some(v) => v,
777+
None => {
778+
return Err(serde::de::Error::invalid_value(
779+
Unexpected::Map,
780+
&"map with a single key",
781+
));
782+
}
783+
};
784+
// enums are encoded in json as maps with a single key:value pair
785+
if iter.next().is_some() {
786+
return Err(serde::de::Error::invalid_value(
787+
Unexpected::Map,
788+
&"map with a single key",
789+
));
790+
}
791+
792+
visitor.visit_enum(EnumRefDeserializer {
793+
variant,
794+
value: Some(value),
795+
})
796+
}
797+
798+
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
799+
where
800+
V: Visitor<'de>,
801+
{
802+
visitor.visit_unit()
803+
}
804+
805+
forward_to_deserialize_any! {
806+
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
807+
bytes byte_buf option unit unit_struct newtype_struct seq tuple
808+
tuple_struct map struct identifier
726809
}
727810
}
728811

@@ -739,7 +822,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
739822
Value::Number(n) => n.deserialize_any(visitor),
740823
Value::String(v) => visitor.visit_borrowed_str(v),
741824
Value::Array(v) => visit_array_ref(v, visitor),
742-
Value::Object(v) => visit_object_ref(v, visitor),
825+
Value::Object(v) => v.deserialize_any(visitor),
743826
}
744827
}
745828

@@ -768,44 +851,24 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
768851

769852
fn deserialize_enum<V>(
770853
self,
771-
_name: &str,
772-
_variants: &'static [&'static str],
854+
name: &'static str,
855+
variants: &'static [&'static str],
773856
visitor: V,
774857
) -> Result<V::Value, Error>
775858
where
776859
V: Visitor<'de>,
777860
{
778-
let (variant, value) = match self {
779-
Value::Object(value) => {
780-
let mut iter = value.into_iter();
781-
let (variant, value) = match iter.next() {
782-
Some(v) => v,
783-
None => {
784-
return Err(serde::de::Error::invalid_value(
785-
Unexpected::Map,
786-
&"map with a single key",
787-
));
788-
}
789-
};
790-
// enums are encoded in json as maps with a single key:value pair
791-
if iter.next().is_some() {
792-
return Err(serde::de::Error::invalid_value(
793-
Unexpected::Map,
794-
&"map with a single key",
795-
));
796-
}
797-
(variant, Some(value))
798-
}
799-
Value::String(variant) => (variant, None),
800-
other => {
801-
return Err(serde::de::Error::invalid_type(
802-
other.unexpected(),
803-
&"string or map",
804-
));
805-
}
806-
};
807-
808-
visitor.visit_enum(EnumRefDeserializer { variant, value })
861+
match self {
862+
Value::Object(value) => value.deserialize_enum(name, variants, visitor),
863+
Value::String(variant) => visitor.visit_enum(EnumRefDeserializer {
864+
variant,
865+
value: None,
866+
}),
867+
other => Err(serde::de::Error::invalid_type(
868+
other.unexpected(),
869+
&"string or map",
870+
)),
871+
}
809872
}
810873

811874
#[inline]
@@ -933,7 +996,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
933996
V: Visitor<'de>,
934997
{
935998
match self {
936-
Value::Object(v) => visit_object_ref(v, visitor),
999+
Value::Object(v) => v.deserialize_any(visitor),
9371000
_ => Err(self.invalid_type(&visitor)),
9381001
}
9391002
}
@@ -949,7 +1012,7 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
9491012
{
9501013
match self {
9511014
Value::Array(v) => visit_array_ref(v, visitor),
952-
Value::Object(v) => visit_object_ref(v, visitor),
1015+
Value::Object(v) => v.deserialize_any(visitor),
9531016
_ => Err(self.invalid_type(&visitor)),
9541017
}
9551018
}
@@ -1046,8 +1109,10 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
10461109
where
10471110
V: Visitor<'de>,
10481111
{
1112+
use serde::de::Deserializer;
1113+
10491114
match self.value {
1050-
Some(Value::Object(v)) => visit_object_ref(v, visitor),
1115+
Some(Value::Object(v)) => v.deserialize_any(visitor),
10511116
Some(other) => Err(serde::de::Error::invalid_type(
10521117
other.unexpected(),
10531118
&"struct variant",

0 commit comments

Comments
 (0)