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