]> git.proxmox.com Git - rustc.git/blob - vendor/darling_core/src/options/mod.rs
New upstream version 1.42.0+dfsg0+pve1
[rustc.git] / vendor / darling_core / src / options / mod.rs
1 use syn;
2
3 use {Error, FromMeta, Result};
4
5 mod core;
6 mod forward_attrs;
7 mod from_derive;
8 mod from_field;
9 mod from_meta;
10 mod from_type_param;
11 mod from_variant;
12 mod input_field;
13 mod input_variant;
14 mod outer_from;
15 mod shape;
16
17 pub use self::core::Core;
18 pub use self::forward_attrs::ForwardAttrs;
19 pub use self::from_derive::FdiOptions;
20 pub use self::from_field::FromFieldOptions;
21 pub use self::from_meta::FromMetaOptions;
22 pub use self::from_type_param::FromTypeParamOptions;
23 pub use self::from_variant::FromVariantOptions;
24 pub use self::input_field::InputField;
25 pub use self::input_variant::InputVariant;
26 pub use self::outer_from::OuterFrom;
27 pub use self::shape::{DataShape, Shape};
28
29 /// A default/fallback expression encountered in attributes during parsing.
30 #[derive(Debug, Clone, PartialEq, Eq)]
31 pub enum DefaultExpression {
32 /// The value should be taken from the `default` instance of the containing struct.
33 /// This is not valid in container options.
34 Inherit,
35 Explicit(syn::Path),
36 Trait,
37 }
38
39 #[doc(hidden)]
40 impl FromMeta for DefaultExpression {
41 fn from_word() -> Result<Self> {
42 Ok(DefaultExpression::Trait)
43 }
44
45 fn from_value(value: &syn::Lit) -> Result<Self> {
46 syn::Path::from_value(value).map(DefaultExpression::Explicit)
47 }
48 }
49
50 /// Run a parsing task, and if it produces an error push it into `$errors`
51 macro_rules! collect_error {
52 ($errors:ident, $task:expr) => {
53 if let Err(e) = $task {
54 $errors.push(e);
55 }
56 };
57 }
58
59 /// Middleware for extracting attribute values. Implementers are expected to override
60 /// `parse_nested` so they can apply individual items to themselves, while `parse_attributes`
61 /// is responsible for looping through distinct outer attributes and collecting errors.
62 pub trait ParseAttribute: Sized {
63 fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> {
64 let mut errors = Vec::new();
65 for attr in attrs {
66 if attr.path == parse_quote!(darling) {
67 collect_error!(errors, parse_attr(attr, &mut self));
68 }
69 }
70
71 if !errors.is_empty() {
72 Err(Error::multiple(errors))
73 } else {
74 Ok(self)
75 }
76 }
77
78 /// Read a meta-item, and apply its values to the current instance.
79 fn parse_nested(&mut self, mi: &syn::Meta) -> Result<()>;
80 }
81
82 fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> {
83 let mut errors = Vec::new();
84 match attr.parse_meta().ok() {
85 Some(syn::Meta::List(data)) => {
86 for item in data.nested {
87 if let syn::NestedMeta::Meta(ref mi) = item {
88 collect_error!(errors, target.parse_nested(mi));
89 } else {
90 panic!("Wasn't able to parse: `{:?}`", item);
91 }
92 }
93
94 if !errors.is_empty() {
95 Err(Error::multiple(errors))
96 } else {
97 Ok(())
98 }
99 }
100 Some(ref item) => panic!("Wasn't able to parse: `{:?}`", item),
101 None => panic!("Unable to parse {:?}", attr),
102 }
103 }
104
105 /// Middleware for extracting values from the body of the derive input. Implementers are
106 /// expected to override `parse_field` or `parse_variant` as appropriate for their use-case,
107 /// while `parse_body` dispatches to the appropriate methods and handles error collection.
108 pub trait ParseData: Sized {
109 fn parse_body(mut self, body: &syn::Data) -> Result<Self> {
110 use syn::{Data, Fields};
111
112 let mut errors = Vec::new();
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 collect_error!(errors, self.parse_field(field));
120 }
121 }
122 Fields::Unnamed(ref fields) => {
123 for field in &fields.unnamed {
124 collect_error!(errors, self.parse_field(field));
125 }
126 }
127 },
128 Data::Enum(ref data) => {
129 for variant in &data.variants {
130 collect_error!(errors, self.parse_variant(variant));
131 }
132 }
133 Data::Union(_) => unreachable!(),
134 };
135
136 if !errors.is_empty() {
137 Err(Error::multiple(errors))
138 } else {
139 Ok(self)
140 }
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 }