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