Skip to main content

darling_core/options/
mod.rs

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