1 | use proc_macro2::TokenStream; |
2 | use quote::ToTokens; |
3 | use syn::Ident; |
4 | |
5 | use crate::codegen::FromDeriveInputImpl; |
6 | use crate::options::{DeriveInputShapeSet, OuterFrom, ParseAttribute, ParseData}; |
7 | use crate::{FromMeta, Result}; |
8 | |
9 | #[derive (Debug)] |
10 | pub struct FdiOptions { |
11 | pub base: OuterFrom, |
12 | |
13 | /// The field on the target struct which should receive the type visibility, if any. |
14 | pub vis: Option<Ident>, |
15 | |
16 | /// The field on the target struct which should receive the type generics, if any. |
17 | pub generics: Option<Ident>, |
18 | |
19 | pub data: Option<Ident>, |
20 | |
21 | pub supports: Option<DeriveInputShapeSet>, |
22 | } |
23 | |
24 | impl FdiOptions { |
25 | pub fn new(di: &syn::DeriveInput) -> Result<Self> { |
26 | (FdiOptions { |
27 | base: OuterFrom::start(di)?, |
28 | vis: Default::default(), |
29 | generics: Default::default(), |
30 | data: Default::default(), |
31 | supports: Default::default(), |
32 | }) |
33 | .parse_attributes(&di.attrs)? |
34 | .parse_body(&di.data) |
35 | } |
36 | } |
37 | |
38 | impl ParseAttribute for FdiOptions { |
39 | fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()> { |
40 | if mi.path().is_ident("supports" ) { |
41 | self.supports = FromMeta::from_meta(item:mi)?; |
42 | Ok(()) |
43 | } else { |
44 | self.base.parse_nested(mi) |
45 | } |
46 | } |
47 | } |
48 | |
49 | impl ParseData for FdiOptions { |
50 | fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> { |
51 | self.base.parse_variant(variant) |
52 | } |
53 | |
54 | fn parse_field(&mut self, field: &syn::Field) -> Result<()> { |
55 | match field.ident.as_ref().map(|v: &Ident| v.to_string()).as_deref() { |
56 | Some("vis" ) => { |
57 | self.vis = field.ident.clone(); |
58 | Ok(()) |
59 | } |
60 | Some("data" ) => { |
61 | self.data = field.ident.clone(); |
62 | Ok(()) |
63 | } |
64 | Some("generics" ) => { |
65 | self.generics = field.ident.clone(); |
66 | Ok(()) |
67 | } |
68 | _ => self.base.parse_field(field), |
69 | } |
70 | } |
71 | } |
72 | |
73 | impl<'a> From<&'a FdiOptions> for FromDeriveInputImpl<'a> { |
74 | fn from(v: &'a FdiOptions) -> Self { |
75 | FromDeriveInputImpl { |
76 | base: (&v.base.container).into(), |
77 | attr_names: &v.base.attr_names, |
78 | from_ident: v.base.from_ident, |
79 | ident: v.base.ident.as_ref(), |
80 | vis: v.vis.as_ref(), |
81 | data: v.data.as_ref(), |
82 | generics: v.generics.as_ref(), |
83 | attrs: v.base.attrs.as_ref(), |
84 | forward_attrs: v.base.forward_attrs.as_ref(), |
85 | supports: v.supports.as_ref(), |
86 | } |
87 | } |
88 | } |
89 | |
90 | impl ToTokens for FdiOptions { |
91 | fn to_tokens(&self, tokens: &mut TokenStream) { |
92 | FromDeriveInputImpl::from(self).to_tokens(tokens) |
93 | } |
94 | } |
95 | |