1 use crate::{Error, FromMeta, Result};
2 
3 mod core;
4 mod forward_attrs;
5 mod from_derive;
6 mod from_field;
7 mod from_meta;
8 mod from_type_param;
9 mod from_variant;
10 mod input_field;
11 mod input_variant;
12 mod outer_from;
13 mod shape;
14 
15 pub use self::core::Core;
16 pub use self::forward_attrs::ForwardAttrs;
17 pub use self::from_derive::FdiOptions;
18 pub use self::from_field::FromFieldOptions;
19 pub use self::from_meta::FromMetaOptions;
20 pub use self::from_type_param::FromTypeParamOptions;
21 pub use self::from_variant::FromVariantOptions;
22 pub use self::input_field::InputField;
23 pub use self::input_variant::InputVariant;
24 pub use self::outer_from::OuterFrom;
25 pub use self::shape::{DataShape, Shape};
26 
27 /// A default/fallback expression encountered in attributes during parsing.
28 #[derive(Debug, Clone, PartialEq, Eq)]
29 pub enum DefaultExpression {
30     /// The value should be taken from the `default` instance of the containing struct.
31     /// This is not valid in container options.
32     Inherit,
33     Explicit(syn::Path),
34     Trait,
35 }
36 
37 #[doc(hidden)]
38 impl FromMeta for DefaultExpression {
from_word() -> Result<Self>39     fn from_word() -> Result<Self> {
40         Ok(DefaultExpression::Trait)
41     }
42 
from_value(value: &syn::Lit) -> Result<Self>43     fn from_value(value: &syn::Lit) -> Result<Self> {
44         syn::Path::from_value(value).map(DefaultExpression::Explicit)
45     }
46 }
47 
48 /// Run a parsing task, and if it produces an error push it into `$errors`
49 macro_rules! collect_error {
50     ($errors:ident, $task:expr) => {
51         if let Err(e) = $task {
52             $errors.push(e);
53         }
54     };
55 }
56 
57 /// Middleware for extracting attribute values. Implementers are expected to override
58 /// `parse_nested` so they can apply individual items to themselves, while `parse_attributes`
59 /// is responsible for looping through distinct outer attributes and collecting errors.
60 pub trait ParseAttribute: Sized {
parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self>61     fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> {
62         let mut errors = Vec::new();
63         for attr in attrs {
64             if attr.path == parse_quote!(darling) {
65                 collect_error!(errors, parse_attr(attr, &mut self));
66             }
67         }
68 
69         if !errors.is_empty() {
70             Err(Error::multiple(errors))
71         } else {
72             Ok(self)
73         }
74     }
75 
76     /// Read a meta-item, and apply its values to the current instance.
parse_nested(&mut self, mi: &syn::Meta) -> Result<()>77     fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()>;
78 }
79 
parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()>80 fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> {
81     let mut errors = Vec::new();
82     match attr.parse_meta().ok() {
83         Some(syn::Meta::List(data)) => {
84             for item in data.nested {
85                 if let syn::NestedMeta::Meta(ref mi) = item {
86                     collect_error!(errors, target.parse_nested(mi));
87                 } else {
88                     panic!("Wasn't able to parse: `{:?}`", item);
89                 }
90             }
91 
92             if !errors.is_empty() {
93                 Err(Error::multiple(errors))
94             } else {
95                 Ok(())
96             }
97         }
98         Some(ref item) => panic!("Wasn't able to parse: `{:?}`", item),
99         None => panic!("Unable to parse {:?}", attr),
100     }
101 }
102 
103 /// Middleware for extracting values from the body of the derive input. Implementers are
104 /// expected to override `parse_field` or `parse_variant` as appropriate for their use-case,
105 /// while `parse_body` dispatches to the appropriate methods and handles error collection.
106 pub trait ParseData: Sized {
parse_body(mut self, body: &syn::Data) -> Result<Self>107     fn parse_body(mut self, body: &syn::Data) -> Result<Self> {
108         use syn::{Data, Fields};
109 
110         let mut errors = Vec::new();
111 
112         match *body {
113             Data::Struct(ref data) => match data.fields {
114                 Fields::Unit => {}
115                 Fields::Named(ref fields) => {
116                     for field in &fields.named {
117                         collect_error!(errors, self.parse_field(field));
118                     }
119                 }
120                 Fields::Unnamed(ref fields) => {
121                     for field in &fields.unnamed {
122                         collect_error!(errors, self.parse_field(field));
123                     }
124                 }
125             },
126             Data::Enum(ref data) => {
127                 for variant in &data.variants {
128                     collect_error!(errors, self.parse_variant(variant));
129                 }
130             }
131             Data::Union(_) => unreachable!(),
132         };
133 
134         if !errors.is_empty() {
135             Err(Error::multiple(errors))
136         } else {
137             Ok(self)
138         }
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