• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use quote::ToTokens;
2 
3 use crate::{ast::Data, codegen::FromAttributesImpl, Error, Result};
4 
5 use super::{OuterFrom, ParseAttribute, ParseData};
6 
7 /// Receiver for derived `FromAttributes` impls.
8 pub struct FromAttributesOptions {
9     // Note: FromAttributes has no behaviors beyond those common
10     // to all the `OuterFrom` traits.
11     pub base: OuterFrom,
12 }
13 
14 impl FromAttributesOptions {
new(di: &syn::DeriveInput) -> Result<Self>15     pub fn new(di: &syn::DeriveInput) -> Result<Self> {
16         let opts = (Self {
17             base: OuterFrom::start(di)?,
18         })
19         .parse_attributes(&di.attrs)?
20         .parse_body(&di.data)?;
21 
22         if !opts.is_newtype() && opts.base.attr_names.is_empty() {
23             Err(Error::custom(
24                 "FromAttributes without attributes collects nothing",
25             ))
26         } else {
27             Ok(opts)
28         }
29     }
30 
is_newtype(&self) -> bool31     fn is_newtype(&self) -> bool {
32         if let Data::Struct(ref data) = self.base.container.data {
33             data.is_newtype()
34         } else {
35             false
36         }
37     }
38 }
39 
40 impl ParseAttribute for FromAttributesOptions {
parse_nested(&mut self, mi: &syn::Meta) -> Result<()>41     fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()> {
42         self.base.parse_nested(mi)
43     }
44 }
45 
46 impl ParseData for FromAttributesOptions {
parse_variant(&mut self, variant: &syn::Variant) -> Result<()>47     fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> {
48         self.base.parse_variant(variant)
49     }
50 
parse_field(&mut self, field: &syn::Field) -> Result<()>51     fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
52         self.base.parse_field(field)
53     }
54 
validate_body(&self, errors: &mut crate::error::Accumulator)55     fn validate_body(&self, errors: &mut crate::error::Accumulator) {
56         self.base.validate_body(errors);
57     }
58 }
59 
60 impl<'a> From<&'a FromAttributesOptions> for FromAttributesImpl<'a> {
from(v: &'a FromAttributesOptions) -> Self61     fn from(v: &'a FromAttributesOptions) -> Self {
62         FromAttributesImpl {
63             base: (&v.base.container).into(),
64             attr_names: &v.base.attr_names,
65             forward_attrs: v.base.as_forward_attrs(),
66         }
67     }
68 }
69 
70 impl ToTokens for FromAttributesOptions {
to_tokens(&self, tokens: &mut proc_macro2::TokenStream)71     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
72         FromAttributesImpl::from(self).to_tokens(tokens)
73     }
74 }
75