fix deserialization of untagged variants within internally or adjacently

tagged enums
This commit is contained in:
Adam H. Leventhal 2023-09-07 17:19:27 -07:00
parent 09993a904a
commit 8da2058e2a
2 changed files with 43 additions and 5 deletions

View File

@ -1749,10 +1749,14 @@ fn deserialize_untagged_enum_after(
); );
let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg); let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg);
// This may be infallible so we need to provide the error type. // Ignore any error associated with non-untagged deserialization so that we
// can fall through to the untagged variants. This may be infallible so we
// need to provide the error type.
let first_attempt = first_attempt.map(|expr| { let first_attempt = first_attempt.map(|expr| {
quote! { quote! {
if let _serde::__private::Result::<_, __D::Error>::Ok(__ok) = #expr { if let _serde::__private::Result::<_, __D::Error>::Ok(__ok) = (|| {
#expr
})() {
return _serde::__private::Ok(__ok); return _serde::__private::Ok(__ok);
} }
} }

View File

@ -2381,11 +2381,12 @@ fn test_partially_untagged_enum_desugared() {
} }
#[test] #[test]
fn test_partially_untagged_simple_enum() { fn test_partially_untagged_tagged_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)] #[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t")] #[serde(tag = "t")]
enum Data { enum Data {
A, A,
B,
#[serde(untagged)] #[serde(untagged)]
Var(u32), Var(u32),
} }
@ -2398,11 +2399,44 @@ fn test_partially_untagged_simple_enum() {
Token::Map { len: None }, Token::Map { len: None },
Token::Str("t"), Token::Str("t"),
Token::Str("A"), Token::Str("A"),
Token::Str("b"),
Token::I32(0),
Token::MapEnd, Token::MapEnd,
], ],
); );
let data = Data::Var(42);
assert_de_tokens(&data, &[Token::U32(42)]);
// TODO test error output
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t", content = "c")]
enum Data2 {
A(u32),
B,
#[serde(untagged)]
Var(u32),
}
let data = Data2::A(7);
assert_de_tokens(
&data,
&[
Token::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::Str("c"),
Token::U32(7),
Token::MapEnd,
],
);
let data = Data2::Var(42);
assert_de_tokens(&data, &[Token::U32(42)]);
// TODO test error output
} }
#[test] #[test]