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