1 use proc_macro2::TokenStream; 2 use quote::{quote, ToTokens}; 3 use syn::Ident; 4 5 use crate::{ 6 codegen::{ExtractAttribute, OuterFromImpl, TraitImpl}, 7 util::PathList, 8 }; 9 10 use super::ForwardAttrs; 11 12 /// `impl FromField` generator. This is used for parsing an individual 13 /// field and its attributes. 14 pub struct FromFieldImpl<'a> { 15 pub ident: Option<&'a Ident>, 16 pub vis: Option<&'a Ident>, 17 pub ty: Option<&'a Ident>, 18 pub base: TraitImpl<'a>, 19 pub attr_names: &'a PathList, 20 pub forward_attrs: ForwardAttrs<'a>, 21 pub from_ident: bool, 22 } 23 24 impl<'a> ToTokens for FromFieldImpl<'a> { to_tokens(&self, tokens: &mut TokenStream)25 fn to_tokens(&self, tokens: &mut TokenStream) { 26 let input = self.param_name(); 27 28 let error_declaration = self.base.declare_errors(); 29 let require_fields = self.base.require_fields(); 30 let error_check = self.base.check_errors(); 31 32 let initializers = self.base.initializers(); 33 34 let default = if self.from_ident { 35 quote!(let __default: Self = ::darling::export::From::from(#input.ident.clone());) 36 } else { 37 self.base.fallback_decl() 38 }; 39 40 let passed_ident = self 41 .ident 42 .as_ref() 43 .map(|i| quote!(#i: #input.ident.clone(),)); 44 let passed_vis = self.vis.as_ref().map(|i| quote!(#i: #input.vis.clone(),)); 45 let passed_ty = self.ty.as_ref().map(|i| quote!(#i: #input.ty.clone(),)); 46 let passed_attrs = self.forward_attrs.as_initializer(); 47 48 // Determine which attributes to forward (if any). 49 let grab_attrs = self.extractor(); 50 let post_transform = self.base.post_transform_call(); 51 52 self.wrap( 53 quote! { 54 fn from_field(#input: &::darling::export::syn::Field) -> ::darling::Result<Self> { 55 #error_declaration 56 57 #grab_attrs 58 59 #require_fields 60 61 #error_check 62 63 #default 64 65 ::darling::export::Ok(Self { 66 #passed_ident 67 #passed_ty 68 #passed_vis 69 #passed_attrs 70 #initializers 71 }) #post_transform 72 73 } 74 }, 75 tokens, 76 ); 77 } 78 } 79 80 impl<'a> ExtractAttribute for FromFieldImpl<'a> { attr_names(&self) -> &PathList81 fn attr_names(&self) -> &PathList { 82 self.attr_names 83 } 84 forward_attrs(&self) -> &super::ForwardAttrs<'_>85 fn forward_attrs(&self) -> &super::ForwardAttrs<'_> { 86 &self.forward_attrs 87 } 88 param_name(&self) -> TokenStream89 fn param_name(&self) -> TokenStream { 90 quote!(__field) 91 } 92 core_loop(&self) -> TokenStream93 fn core_loop(&self) -> TokenStream { 94 self.base.core_loop() 95 } 96 local_declarations(&self) -> TokenStream97 fn local_declarations(&self) -> TokenStream { 98 self.base.local_declarations() 99 } 100 } 101 102 impl<'a> OuterFromImpl<'a> for FromFieldImpl<'a> { trait_path(&self) -> syn::Path103 fn trait_path(&self) -> syn::Path { 104 path!(::darling::FromField) 105 } 106 trait_bound(&self) -> syn::Path107 fn trait_bound(&self) -> syn::Path { 108 path!(::darling::FromMeta) 109 } 110 base(&'a self) -> &'a TraitImpl<'a>111 fn base(&'a self) -> &'a TraitImpl<'a> { 112 &self.base 113 } 114 } 115