From 94b857057b090e11f128bb6dd8c36f99224e790b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 6 May 2018 20:39:45 -0700 Subject: [PATCH] Support deserializing enums containing flatten --- serde_derive/src/de.rs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index f1a37b85..e3197fcf 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -838,6 +838,10 @@ fn deserialize_struct( quote! { _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) } + } else if is_enum && cattrs.has_flatten() { + quote! { + _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) + } } else if is_enum { quote! { _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) @@ -875,6 +879,23 @@ fn deserialize_struct( _ => None, }; + let visitor_seed = if is_enum && cattrs.has_flatten() { + Some(quote! { + impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_map(__deserializer, self) + } + } + }) + } else { + None + }; + quote_block! { #field_visitor @@ -901,6 +922,8 @@ fn deserialize_struct( } } + #visitor_seed + #fields_stmt #dispatch @@ -1738,7 +1761,7 @@ fn deserialize_generated_identifier( let this = quote!(__Field); let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); - let (ignore_variant, fallthrough) = if cattrs.has_flatten() { + let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() { let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),); let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value))); (Some(ignore_variant), Some(fallthrough)) @@ -1755,10 +1778,10 @@ fn deserialize_generated_identifier( fields, is_variant, fallthrough, - cattrs.has_flatten(), + !is_variant && cattrs.has_flatten(), )); - let lifetime = if cattrs.has_flatten() { + let lifetime = if !is_variant && cattrs.has_flatten() { Some(quote!(<'de>)) } else { None