From b86a46c83cd3c69af8b442d1e571064694213da8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 7 Sep 2019 20:32:26 -0700 Subject: [PATCH] Factor skipping in newtype variants into effective_style --- serde_derive/src/de.rs | 67 ++++++++++++++++++++++------------------- serde_derive/src/ser.rs | 48 +++++++---------------------- 2 files changed, 47 insertions(+), 68 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 1ce32184..5ed28617 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1688,22 +1688,12 @@ fn deserialize_externally_tagged_variant( _serde::export::Ok(#this::#variant_ident) } } - Style::Newtype => { - if variant.fields[0].attrs.skip_deserializing() { - let this = ¶ms.this; - let let_default = match variant.fields[0].attrs.default() { - attr::Default::Default => quote!(_serde::export::Default::default()), - attr::Default::Path(ref path) => quote!(#path()), - attr::Default::None => unimplemented!(), - }; - - return quote_block! { - try!(_serde::de::VariantAccess::unit_variant(__variant)); - _serde::export::Ok(#this::#variant_ident(#let_default)) - }; - } - deserialize_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0]) - } + Style::Newtype => deserialize_externally_tagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + cattrs, + ), Style::Tuple => { deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None) } @@ -1730,14 +1720,18 @@ fn deserialize_internally_tagged_variant( let variant_ident = &variant.ident; - match variant.style { + match effective_style(variant) { Style::Unit => { let this = ¶ms.this; let type_name = params.type_name(); let variant_name = variant.ident.to_string(); + let default = variant.fields.get(0).map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); quote_block! { try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); - _serde::export::Ok(#this::#variant_ident) + _serde::export::Ok(#this::#variant_ident #default) } } Style::Newtype => deserialize_untagged_newtype_variant( @@ -1775,17 +1769,21 @@ fn deserialize_untagged_variant( let variant_ident = &variant.ident; - match variant.style { + match effective_style(variant) { Style::Unit => { let this = ¶ms.this; let type_name = params.type_name(); let variant_name = variant.ident.to_string(); + let default = variant.fields.get(0).map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); quote_expr! { match _serde::Deserializer::deserialize_any( #deserializer, _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) ) { - _serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident), + _serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident #default), _serde::export::Err(__err) => _serde::export::Err(__err), } } @@ -1818,8 +1816,19 @@ fn deserialize_externally_tagged_newtype_variant( variant_ident: &syn::Ident, params: &Parameters, field: &Field, + cattrs: &attr::Container, ) -> Fragment { let this = ¶ms.this; + + if field.attrs.skip_deserializing() { + let this = ¶ms.this; + let default = Expr(expr_is_missing(field, cattrs)); + return quote_block! { + try!(_serde::de::VariantAccess::unit_variant(__variant)); + _serde::export::Ok(#this::#variant_ident(#default)) + }; + } + match field.attrs.deserialize_with() { None => { let field_ty = field.ty; @@ -1852,17 +1861,6 @@ fn deserialize_untagged_newtype_variant( let field_ty = field.ty; match field.attrs.deserialize_with() { None => { - if field.attrs.skip_deserializing() { - let let_default = match field.attrs.default() { - attr::Default::Default => quote!(_serde::export::Default::default()), - attr::Default::Path(ref path) => quote!(#path()), - attr::Default::None => unimplemented!(), - }; - - return quote_expr! { - _serde::export::Ok(#this::#variant_ident(#let_default)) - }; - } let span = field.original.span(); let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); quote_expr! { @@ -2904,6 +2902,13 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { } } +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit, + other => other, + } +} + struct DeImplGenerics<'a>(&'a Parameters); #[cfg(feature = "deserialize_in_place")] struct InPlaceImplGenerics<'a>(&'a Parameters); diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index e2065b7b..7bf967da 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -509,7 +509,7 @@ fn serialize_externally_tagged_variant( }; } - match variant.style { + match effective_style(variant) { Style::Unit => { quote_expr! { _serde::Serializer::serialize_unit_variant( @@ -522,16 +522,6 @@ fn serialize_externally_tagged_variant( } Style::Newtype => { let field = &variant.fields[0]; - if field.attrs.skip_serializing() { - return quote_expr! { - _serde::Serializer::serialize_unit_variant( - __serializer, - #type_name, - #variant_index, - #variant_name, - ) - }; - } let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); @@ -596,7 +586,7 @@ fn serialize_internally_tagged_variant( }; } - match variant.style { + match effective_style(variant) { Style::Unit => { quote_block! { let mut __struct = try!(_serde::Serializer::serialize_struct( @@ -608,15 +598,6 @@ fn serialize_internally_tagged_variant( } Style::Newtype => { let field = &variant.fields[0]; - if field.attrs.skip_serializing() { - return quote_block! { - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 1)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); - _serde::ser::SerializeStruct::end(__struct) - }; - } let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); @@ -665,7 +646,7 @@ fn serialize_adjacently_tagged_variant( _serde::Serialize::serialize(#ser, __serializer) } } else { - match variant.style { + match effective_style(variant) { Style::Unit => { return quote_block! { let mut __struct = try!(_serde::Serializer::serialize_struct( @@ -677,15 +658,6 @@ fn serialize_adjacently_tagged_variant( } Style::Newtype => { let field = &variant.fields[0]; - if field.attrs.skip_serializing() { - return quote_block! { - let mut __struct = try!(_serde::Serializer::serialize_struct( - __serializer, #type_name, 1)); - try!(_serde::ser::SerializeStruct::serialize_field( - &mut __struct, #tag, #variant_name)); - _serde::ser::SerializeStruct::end(__struct) - }; - } let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); @@ -781,7 +753,7 @@ fn serialize_untagged_variant( }; } - match variant.style { + match effective_style(variant) { Style::Unit => { quote_expr! { _serde::Serializer::serialize_unit(__serializer) @@ -789,11 +761,6 @@ fn serialize_untagged_variant( } Style::Newtype => { let field = &variant.fields[0]; - if field.attrs.skip_serializing() { - return quote_expr! { - _serde::Serializer::serialize_unit(__serializer) - }; - } let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); @@ -1291,6 +1258,13 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStrea } } +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit, + other => other, + } +} + enum StructTrait { SerializeMap, SerializeStruct,