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::{Error, FromMeta, Result};
7
8mod core;
9mod forward_attrs;
10mod from_attributes;
11mod from_derive;
12mod from_field;
13mod from_meta;
14mod from_type_param;
15mod from_variant;
16mod input_field;
17mod input_variant;
18mod outer_from;
19mod shape;
20
21pub use self::core::Core;
22pub use self::forward_attrs::{AttrsField, ForwardAttrsFilter};
23pub use self::from_attributes::FromAttributesOptions;
24pub use self::from_derive::FdiOptions;
25pub use self::from_field::FromFieldOptions;
26pub use self::from_meta::FromMetaOptions;
27pub use self::from_type_param::FromTypeParamOptions;
28pub use self::from_variant::FromVariantOptions;
29pub use self::input_field::InputField;
30pub use self::input_variant::InputVariant;
31pub use self::outer_from::OuterFrom;
32pub use self::shape::{DataShape, DeriveInputShapeSet};
33
34#[derive(Debug, Clone)]
36pub enum DefaultExpression {
37 Inherit,
40 Explicit(syn::Path),
41 Trait {
42 span: Span,
44 },
45}
46
47#[doc(hidden)]
48impl FromMeta for DefaultExpression {
49 fn from_meta(item: &syn::Meta) -> Result<Self> {
52 match item {
53 syn::Meta::Path(_) => Ok(DefaultExpression::Trait { span: item.span() }),
54 syn::Meta::List(nm) => Err(Error::unsupported_format("list").with_span(nm)),
55 syn::Meta::NameValue(nv) => Self::from_expr(&nv.value),
56 }
57 }
58
59 fn from_expr(expr: &syn::Expr) -> Result<Self> {
60 syn::Path::from_expr(expr).map(DefaultExpression::Explicit)
61 }
62
63 fn from_value(value: &syn::Lit) -> Result<Self> {
64 syn::Path::from_value(value).map(DefaultExpression::Explicit)
65 }
66}
67
68pub trait ParseAttribute: Sized {
72 fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> {
73 let mut errors = Error::accumulator();
74 for attr in attrs {
75 if attr.meta.path() == &parse_quote!(darling) {
76 errors.handle(parse_attr(attr, &mut self));
77 }
78 }
79
80 errors.finish_with(self)
81 }
82
83 fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()>;
85}
86
87fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> {
88 let mut errors = Error::accumulator();
89 match &attr.meta {
90 syn::Meta::List(data) => {
91 for item in NestedMeta::parse_meta_list(data.tokens.clone())? {
92 if let NestedMeta::Meta(ref mi) = item {
93 errors.handle(target.parse_nested(mi));
94 } else {
95 panic!("Wasn't able to parse: `{:?}`", item);
96 }
97 }
98
99 errors.finish()
100 }
101 item => panic!("Wasn't able to parse: `{:?}`", item),
102 }
103}
104
105pub trait ParseData: Sized {
109 fn parse_body(mut self, body: &syn::Data) -> Result<Self> {
110 use syn::{Data, Fields};
111
112 let mut errors = Error::accumulator();
113
114 match *body {
115 Data::Struct(ref data) => match data.fields {
116 Fields::Unit => {}
117 Fields::Named(ref fields) => {
118 for field in &fields.named {
119 errors.handle(self.parse_field(field));
120 }
121 }
122 Fields::Unnamed(ref fields) => {
123 for field in &fields.unnamed {
124 errors.handle(self.parse_field(field));
125 }
126 }
127 },
128 Data::Enum(ref data) => {
129 for variant in &data.variants {
130 errors.handle(self.parse_variant(variant));
131 }
132 }
133 Data::Union(_) => unreachable!(),
134 };
135
136 self.validate_body(&mut errors);
137
138 errors.finish_with(self)
139 }
140
141 fn parse_variant(&mut self, variant: &syn::Variant) -> Result<()> {
144 Err(Error::unsupported_format("enum variant").with_span(variant))
145 }
146
147 fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
150 Err(Error::unsupported_format("struct field").with_span(field))
151 }
152
153 #[allow(unused_variables)]
157 fn validate_body(&self, errors: &mut Accumulator) {}
158}