Skip to content

Commit 2ac3ff7

Browse files
committed
Provide an implementation of deserialize_any
`deserialize_any` is necessary to handle untagged enum variants. Signed-off-by: Chris Frantz <[email protected]>
1 parent e49e2dd commit 2ac3ff7

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

src/de.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,28 @@ where
8585
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
8686
type Error = Error;
8787

88-
fn deserialize_any<V>(self, _v: V) -> Result<V::Value>
88+
fn deserialize_any<V>(self, v: V) -> Result<V::Value>
8989
where
9090
V: Visitor<'de>,
9191
{
92-
unimplemented!();
92+
match self.doc {
93+
Document::String(s, _) => v.visit_str(s.as_str()),
94+
Document::StaticStr(s, _) => v.visit_str(s),
95+
Document::Boolean(b) => v.visit_bool(*b),
96+
Document::Int(i) => v.visit_i64(i.into()),
97+
Document::Float(f) => v.visit_f64(*f),
98+
Document::Mapping(map) => {
99+
v.visit_map(Sequence::new(map.iter().filter(|f| f.has_value())))
100+
}
101+
Document::Sequence(seq) => {
102+
v.visit_seq(Sequence::new(seq.iter().filter(|f| f.has_value())))
103+
}
104+
Document::Bytes(b) => v.visit_bytes(b.as_slice()),
105+
Document::Null => v.visit_unit(),
106+
Document::Compact(_) => unimplemented!(),
107+
Document::Fragment(_) => unimplemented!(),
108+
Document::Comment(_, _) => unimplemented!(),
109+
}
93110
}
94111
fn deserialize_ignored_any<V>(self, _v: V) -> Result<V::Value>
95112
where

tests/test_format.rs

+55
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,58 @@ fn test_bytes() -> Result<()> {
517517

518518
Ok(())
519519
}
520+
521+
#[derive(Serialize, Deserialize, Debug, PartialEq)]
522+
#[serde(untagged)]
523+
enum Data {
524+
None,
525+
Bool(bool),
526+
Int(i64),
527+
Str(String),
528+
List(Vec<Data>),
529+
}
530+
531+
#[derive(Serialize, Deserialize, Debug, PartialEq)]
532+
struct VariousData {
533+
none: Data,
534+
boolean: Data,
535+
integer: Data,
536+
string: Data,
537+
list: Data,
538+
}
539+
540+
#[test]
541+
fn test_untagged_data() -> Result<()> {
542+
let value = VariousData {
543+
none: Data::None,
544+
boolean: Data::Bool(true),
545+
integer: Data::Int(100),
546+
string: Data::Str("hello".into()),
547+
list: Data::List(vec![
548+
Data::None,
549+
Data::Bool(false),
550+
Data::Int(200),
551+
Data::Str("bye".into()),
552+
]),
553+
};
554+
555+
tester!(
556+
relax, // Use the 'relax' parser to test our deserializer.
557+
VariousData,
558+
&value,
559+
r#"
560+
{
561+
"none": null,
562+
"boolean": true,
563+
"integer": 100,
564+
"string": "hello",
565+
"list": [
566+
null,
567+
false,
568+
200,
569+
"bye"
570+
]
571+
}"#
572+
);
573+
Ok(())
574+
}

0 commit comments

Comments
 (0)