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