]>
Commit | Line | Data |
---|---|---|
dc9dc135 XL |
1 | use proc_macro2::TokenStream; |
2 | use quote::ToTokens; | |
3 | use syn::{self, Ident}; | |
4 | ||
5 | use codegen::FromDeriveInputImpl; | |
6 | use options::{OuterFrom, ParseAttribute, ParseData, Shape}; | |
7 | use {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<Shape>, | |
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 | match mi.name().to_string().as_str() { | |
41 | "supports" => { | |
42 | self.supports = FromMeta::from_meta(mi)?; | |
43 | Ok(()) | |
44 | } | |
45 | _ => self.base.parse_nested(mi), | |
46 | } | |
47 | } | |
48 | } | |
49 | ||
50 | impl ParseData for FdiOptions { | |
51 | fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> { | |
52 | self.base.parse_variant(variant) | |
53 | } | |
54 | ||
55 | fn parse_field(&mut self, field: &syn::Field) -> Result<()> { | |
56 | match field | |
57 | .ident | |
58 | .as_ref() | |
59 | .map(|v| v.to_string()) | |
60 | .as_ref() | |
61 | .map(|v| v.as_str()) | |
62 | { | |
63 | Some("vis") => { | |
64 | self.vis = field.ident.clone(); | |
65 | Ok(()) | |
66 | } | |
67 | Some("data") => { | |
68 | self.data = field.ident.clone(); | |
69 | Ok(()) | |
70 | } | |
71 | Some("generics") => { | |
72 | self.generics = field.ident.clone(); | |
73 | Ok(()) | |
74 | } | |
75 | _ => self.base.parse_field(field), | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | impl<'a> From<&'a FdiOptions> for FromDeriveInputImpl<'a> { | |
81 | fn from(v: &'a FdiOptions) -> Self { | |
82 | FromDeriveInputImpl { | |
83 | base: (&v.base.container).into(), | |
84 | attr_names: &v.base.attr_names, | |
85 | from_ident: v.base.from_ident, | |
86 | ident: v.base.ident.as_ref(), | |
87 | vis: v.vis.as_ref(), | |
88 | data: v.data.as_ref(), | |
89 | generics: v.generics.as_ref(), | |
90 | attrs: v.base.attrs.as_ref(), | |
91 | forward_attrs: v.base.forward_attrs.as_ref(), | |
92 | supports: v.supports.as_ref(), | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
97 | impl ToTokens for FdiOptions { | |
98 | fn to_tokens(&self, tokens: &mut TokenStream) { | |
99 | FromDeriveInputImpl::from(self).to_tokens(tokens) | |
100 | } | |
101 | } |