From 77b3293e5698e313284ed51f334be5fc0903086f Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 22 Jul 2023 22:43:11 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=B0=D1=82=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D0=B5=D0=BC=20skip=20=D0=B2=20variant-with?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- serde_derive/src/de.rs | 66 ++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 13cbff6d6..198575d57 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -10,7 +10,7 @@ use std::ptr; use std::sync::atomic::Ordering; use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{parse_quote, Ident, Index, Member}; +use syn::{parse_quote, Ident, Index}; pub fn expand_derive_deserialize(input: &mut syn::DeriveInput) -> syn::Result { replace_receiver(input); @@ -1859,10 +1859,16 @@ fn deserialize_externally_tagged_variant( ) -> Fragment { // Feature https://github.com/serde-rs/serde/issues/1013 if let Some(path) = variant.attrs.deserialize_with() { - let field_tys = variant.fields.iter().map(|field| field.ty); + let field_tys = variant.fields.iter().filter_map(|field| { + if field.attrs.skip_deserializing() { + None + } else { + Some(field.ty) + } + }); let (wrapper, wrapper_ty) = wrap_deserialize_with(params, "e!((#(#field_tys),*)), path); - let unwrap_fn = unwrap_to_variant_closure(params, variant, true); + let unwrap_fn = unwrap_to_variant_closure(params, variant, cattrs, true); return quote_block! { #wrapper @@ -1949,7 +1955,7 @@ fn deserialize_untagged_variant( ) -> Fragment { // Feature https://github.com/serde-rs/serde/issues/1013 if let Some(path) = variant.attrs.deserialize_with() { - let unwrap_fn = unwrap_to_variant_closure(params, variant, false); + let unwrap_fn = unwrap_to_variant_closure(params, variant, cattrs, false); return quote_block! { _serde::__private::Result::map(#path(#deserializer), #unwrap_fn) }; @@ -3013,26 +3019,24 @@ fn wrap_deserialize_field_with( fn unwrap_to_variant_closure( params: &Parameters, variant: &Variant, + cattrs: &attr::Container, with_wrapper: bool, ) -> TokenStream { let this_value = ¶ms.this_value; let variant_ident = &variant.ident; + let fields = variant + .fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()); let (arg, wrapper) = if with_wrapper { (quote! { __wrap }, quote! { __wrap.value }) } else { - let field_tys = variant.fields.iter().map(|field| field.ty); + let field_tys = fields.clone().map(|field| field.ty); (quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap }) }; - let field_access = (0..variant.fields.len()).map(|n| { - Member::Unnamed(Index { - index: n as u32, - span: Span::call_site(), - }) - }); - - match variant.style { + match variant.de_style() { Style::Struct if variant.fields.len() == 1 => { let member = &variant.fields[0].member; quote! { @@ -3040,14 +3044,40 @@ fn unwrap_to_variant_closure( } } Style::Struct => { - let members = variant.fields.iter().map(|field| &field.member); + let mut i = 0; + let members = variant.fields.iter().map(|field| { + let name = &field.member; + let index = Index::from(i); + i += 1; + + if field.attrs.skip_deserializing() { + let expr = Expr(expr_is_missing(&field, cattrs)); + quote!(#name: #expr) + } else { + quote!(#name: #wrapper.#index) + } + }); quote! { - |#arg| #this_value::#variant_ident { #(#members: #wrapper.#field_access),* } + |#arg| #this_value::#variant_ident { #(#members),* } + } + } + Style::Tuple => { + let mut i = 0; + let members = variant.fields.iter().map(|field| { + let index = Index::from(i); + i += 1; + + if field.attrs.skip_deserializing() { + let expr = Expr(expr_is_missing(&field, cattrs)); + quote!(#expr) + } else { + quote!(#wrapper.#index) + } + }); + quote! { + |#arg| #this_value::#variant_ident(#(#members),*) } } - Style::Tuple => quote! { - |#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*) - }, Style::Newtype => quote! { |#arg| #this_value::#variant_ident(#wrapper) },