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