darling_core/options/
mod.rs1use 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#[derive(Debug, Clone)]
39pub enum DefaultExpression {
40 Inherit,
43 Explicit(Callable),
45 Trait {
46 span: Span,
48 },
49}
50
51#[doc(hidden)]
52impl FromMeta for DefaultExpression {
53 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
72pub 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 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
109pub 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 fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> {
148 Err(Error::unsupported_format("enum variant").with_span(variant))
149 }
150
151 fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
154 Err(Error::unsupported_format("struct field").with_span(field))
155 }
156
157 #[allow(unused_variables)]
161 fn validate_body(&self, errors: &mut Accumulator) {}
162}