1 use proc_macro2::TokenStream; 2 use quote::ToTokens; 3 use syn::Ident; 4 5 use crate::codegen::FromFieldImpl; 6 use crate::options::{OuterFrom, ParseAttribute, ParseData}; 7 use crate::Result; 8 9 #[derive(Debug)] 10 pub struct FromFieldOptions { 11 pub base: OuterFrom, 12 pub vis: Option<Ident>, 13 pub ty: Option<Ident>, 14 } 15 16 impl FromFieldOptions { new(di: &syn::DeriveInput) -> Result<Self>17 pub fn new(di: &syn::DeriveInput) -> Result<Self> { 18 (FromFieldOptions { 19 base: OuterFrom::start(di)?, 20 vis: Default::default(), 21 ty: Default::default(), 22 }) 23 .parse_attributes(&di.attrs)? 24 .parse_body(&di.data) 25 } 26 } 27 28 impl ParseAttribute for FromFieldOptions { parse_nested(&mut self, mi: &syn::Meta) -> Result<()>29 fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()> { 30 self.base.parse_nested(mi) 31 } 32 } 33 34 impl ParseData for FromFieldOptions { parse_variant(&mut self, variant: &syn::Variant) -> Result<()>35 fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> { 36 self.base.parse_variant(variant) 37 } 38 parse_field(&mut self, field: &syn::Field) -> Result<()>39 fn parse_field(&mut self, field: &syn::Field) -> Result<()> { 40 match field.ident.as_ref().map(|v| v.to_string()).as_deref() { 41 Some("vis") => { 42 self.vis.clone_from(&field.ident); 43 Ok(()) 44 } 45 Some("ty") => { 46 self.ty.clone_from(&field.ident); 47 Ok(()) 48 } 49 _ => self.base.parse_field(field), 50 } 51 } 52 validate_body(&self, errors: &mut crate::error::Accumulator)53 fn validate_body(&self, errors: &mut crate::error::Accumulator) { 54 self.base.validate_body(errors); 55 } 56 } 57 58 impl<'a> From<&'a FromFieldOptions> for FromFieldImpl<'a> { from(v: &'a FromFieldOptions) -> Self59 fn from(v: &'a FromFieldOptions) -> Self { 60 FromFieldImpl { 61 ident: v.base.ident.as_ref(), 62 vis: v.vis.as_ref(), 63 ty: v.ty.as_ref(), 64 base: (&v.base.container).into(), 65 attr_names: &v.base.attr_names, 66 forward_attrs: v.base.as_forward_attrs(), 67 from_ident: v.base.from_ident, 68 } 69 } 70 } 71 72 impl ToTokens for FromFieldOptions { to_tokens(&self, tokens: &mut TokenStream)73 fn to_tokens(&self, tokens: &mut TokenStream) { 74 FromFieldImpl::from(self).to_tokens(tokens) 75 } 76 } 77