From 27478b6f717fcafbde971aa5a5ad1f8799ac2949 Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 6 Sep 2018 14:29:49 -0700 Subject: [PATCH 1/2] Internally tagged unit enum variants should ignore unknown fields. --- serde/src/private/de.rs | 7 ++++--- test_suite/tests/test_annotations.rs | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 8fb40ff18..51c7035a3 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -231,8 +231,8 @@ mod content { use super::size_hint; use de::{ - self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess, - SeqAccess, Unexpected, Visitor, + self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, + MapAccess, SeqAccess, Unexpected, Visitor, }; /// Used from generated code to buffer the contents of the Deserializer when @@ -2470,10 +2470,11 @@ mod content { Ok(()) } - fn visit_map(self, _: M) -> Result<(), M::Error> + fn visit_map(self, mut access: M) -> Result<(), M::Error> where M: MapAccess<'de>, { + while let Some(_) = try!(access.next_entry::()) {} Ok(()) } } diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 55455b043..b3bd7a797 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2246,3 +2246,26 @@ fn test_transparent_tuple_struct() { assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]); } + +#[test] +fn test_internally_tagged_unit_enum_with_unknown_fields() { + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "t")] + enum Data { + A, + } + + let data = Data::A; + + assert_de_tokens( + &data, + &[ + Token::Map { len: None }, + Token::Str("t"), + Token::Str("A"), + Token::Str("b"), + Token::I32(0), + Token::MapEnd, + ], + ); +} From 389b9b5fe70dd6ffaa111f517c30da438a39df7a Mon Sep 17 00:00:00 2001 From: David Reid Date: Thu, 6 Sep 2018 14:55:10 -0700 Subject: [PATCH 2/2] Add a test for an internally tagged unit enum flattened with a second internally tagged unit enum. --- test_suite/tests/test_annotations.rs | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index b3bd7a797..87eda5015 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -2269,3 +2269,45 @@ fn test_internally_tagged_unit_enum_with_unknown_fields() { ], ); } + +#[test] +fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { + #[derive(Deserialize, PartialEq, Debug)] + struct S { + #[serde(flatten)] + x: X, + #[serde(flatten)] + y: Y, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeX")] + enum X { + A, + } + + #[derive(Deserialize, PartialEq, Debug)] + #[serde(tag = "typeY")] + enum Y { + B { c: u32 }, + } + + let s = S { + x: X::A, + y: Y::B { c: 0 }, + }; + + assert_de_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("typeX"), + Token::Str("A"), + Token::Str("typeY"), + Token::Str("B"), + Token::Str("c"), + Token::I32(0), + Token::MapEnd, + ], + ); +}