Merge pull request #1376 from dreid/fix-internally-tagged-enum-deserialization-with-unknown-fields

Fix internally tagged enum deserialization with unknown fields
This commit is contained in:
David Tolnay 2018-09-06 21:10:41 -07:00 committed by GitHub
commit 8d5cda8464
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 3 deletions

View File

@ -231,8 +231,8 @@ mod content {
use super::size_hint; use super::size_hint;
use de::{ use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess, self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
SeqAccess, Unexpected, Visitor, MapAccess, SeqAccess, Unexpected, Visitor,
}; };
/// Used from generated code to buffer the contents of the Deserializer when /// Used from generated code to buffer the contents of the Deserializer when
@ -2470,10 +2470,11 @@ mod content {
Ok(()) Ok(())
} }
fn visit_map<M>(self, _: M) -> Result<(), M::Error> fn visit_map<M>(self, mut access: M) -> Result<(), M::Error>
where where
M: MapAccess<'de>, M: MapAccess<'de>,
{ {
while let Some(_) = try!(access.next_entry::<IgnoredAny, IgnoredAny>()) {}
Ok(()) Ok(())
} }
} }

View File

@ -2246,3 +2246,68 @@ fn test_transparent_tuple_struct() {
assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]); 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,
],
);
}
#[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,
],
);
}