1 use proc_macro2::Span;
2 use syn::{parse_quote, spanned::Spanned};
3 
4 use crate::ast::NestedMeta;
5 use crate::error::Accumulator;
6 use crate::{Error, FromMeta, Result};
7 
8 mod core;
9 mod forward_attrs;
10 mod from_attributes;
11 mod from_derive;
12 mod from_field;
13 mod from_meta;
14 mod from_type_param;
15 mod from_variant;
16 mod input_field;
17 mod input_variant;
18 mod outer_from;
19 mod shape;
20 
21 pub use self::core::Core;
22 pub use self::forward_attrs::{AttrsField, ForwardAttrsFilter};
23 pub use self::from_attributes::FromAttributesOptions;
24 pub use self::from_derive::FdiOptions;
25 pub use self::from_field::FromFieldOptions;
26 pub use self::from_meta::FromMetaOptions;
27 pub use self::from_type_param::FromTypeParamOptions;
28 pub use self::from_variant::FromVariantOptions;
29 pub use self::input_field::InputField;
30 pub use self::input_variant::InputVariant;
31 pub use self::outer_from::OuterFrom;
32 pub use self::shape::{DataShape, DeriveInputShapeSet};
33 
34 /// A default/fallback expression encountered in attributes during parsing.
35 #[derive(Debug, Clone)]
36 pub enum DefaultExpression {
37     /// The value should be taken from the `default` instance of the containing struct.
38     /// This is not valid in container options.
39     Inherit,
40     Explicit(syn::Path),
41     Trait {
42         /// The input span that is responsible for the use of `Default::default`.
43         span: Span,
44     },
45 }
46 
47 #[doc(hidden)]
48 impl FromMeta for DefaultExpression {
49     // Note: This cannot use `from_word` as it needs to capture the span
50     // in the `Meta::Path` case.
from_meta(item: &syn::Meta) -> Result<Self>51     fn from_meta(item: &syn::Meta) -> Result<Self> {
52         match item {
53             syn::Meta::Path(_) => Ok(DefaultExpression::Trait { span: item.span() }),
54             syn::Meta::List(nm) => Err(Error::unsupported_format("list").with_span(nm)),
55             syn::Meta::NameValue(nv) => Self::from_expr(&nv.value),
56         }
57     }
58 
from_expr(expr: &syn::Expr) -> Result<Self>59     fn from_expr(expr: &syn::Expr) -> Result<Self> {
60         syn::Path::from_expr(expr).map(DefaultExpression::Explicit)
61     }
62 
from_value(value: &syn::Lit) -> Result<Self>63     fn from_value(value: &syn::Lit) -> Result<Self> {
64         syn::Path::from_value(value).map(DefaultExpression::Explicit)
65     }
66 }
67 
68 /// Middleware for extracting attribute values. Implementers are expected to override
69 /// `parse_nested` so they can apply individual items to themselves, while `parse_attributes`
70 /// is responsible for looping through distinct outer attributes and collecting errors.
71 pub trait ParseAttribute: Sized {
parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self>72     fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> {
73         let mut errors = Error::accumulator();
74         for attr in attrs {
75             if attr.meta.path() == &parse_quote!(darling) {
76                 errors.handle(parse_attr(attr, &mut self));
77             }
78         }
79 
80         errors.finish_with(self)
81     }
82 
83     /// Read a meta-item, and apply its values to the current instance.
parse_nested(&mut self, mi: &syn::Meta) -> Result<()>84     fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()>;
85 }
86 
parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()>87 fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> {
88     let mut errors = Error::accumulator();
89     match &attr.meta {
90         syn::Meta::List(data) => {
91             for item in NestedMeta::parse_meta_list(data.tokens.clone())? {
92                 if let NestedMeta::Meta(ref mi) = item {
93                     errors.handle(target.parse_nested(mi));
94                 } else {
95                     panic!("Wasn't able to parse: `{:?}`", item);
96                 }
97             }
98 
99             errors.finish()
100         }
101         item => panic!("Wasn't able to parse: `{:?}`", item),
102     }
103 }
104 
105 /// Middleware for extracting values from the body of the derive input. Implementers are
106 /// expected to override `parse_field` or `parse_variant` as appropriate for their use-case,
107 /// while `parse_body` dispatches to the appropriate methods and handles error collection.
108 pub trait ParseData: Sized {
parse_body(mut self, body: &syn::Data) -> Result<Self>109     fn parse_body(mut self, body: &syn::Data) -> Result<Self> {
110         use syn::{Data, Fields};
111 
112         let mut errors = Error::accumulator();
113 
114         match *body {
115             Data::Struct(ref data) => match data.fields {
116                 Fields::Unit => {}
117                 Fields::Named(ref fields) => {
118                     for field in &fields.named {
119                         errors.handle(self.parse_field(field));
120                     }
121                 }
122                 Fields::Unnamed(ref fields) => {
123                     for field in &fields.unnamed {
124                         errors.handle(self.parse_field(field));
125                     }
126                 }
127             },
128             Data::Enum(ref data) => {
129                 for variant in &data.variants {
130                     errors.handle(self.parse_variant(variant));
131                 }
132             }
133             Data::Union(_) => unreachable!(),
134         };
135 
136         self.validate_body(&mut errors);
137 
138         errors.finish_with(self)
139     }
140 
141     /// Apply the next found variant to the object, returning an error
142     /// if parsing goes wrong.
parse_variant(&mut self, variant: &syn::Variant) -> Result<()>143     fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> {
144         Err(Error::unsupported_format("enum variant").with_span(variant))
145     }
146 
147     /// Apply the next found struct field to the object, returning an error
148     /// if parsing goes wrong.
parse_field(&mut self, field: &syn::Field) -> Result<()>149     fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
150         Err(Error::unsupported_format("struct field").with_span(field))
151     }
152 
153     /// Perform validation checks that require data from more than one field or variant.
154     /// The default implementation does no validations.
155     /// Implementors can override this method as appropriate for their use-case.
156     #[allow(unused_variables)]
validate_body(&self, errors: &mut Accumulator)157     fn validate_body(&self, errors: &mut Accumulator) {}
158 }
159