1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn;
use ast::{Data, Fields, Style};
use codegen::{Field, OuterFromImpl, TraitImpl, Variant};
pub struct FromMetaImpl<'a> {
pub base: TraitImpl<'a>,
}
impl<'a> ToTokens for FromMetaImpl<'a> {
fn to_tokens(&self, tokens: &mut TokenStream) {
let base = &self.base;
let impl_block = match base.data {
Data::Struct(ref vd) if vd.style.is_unit() => {
let ty_ident = base.ident;
quote!(
fn from_word() -> ::darling::Result<Self> {
::darling::export::Ok(#ty_ident)
}
)
}
Data::Struct(Fields {
ref fields,
style: Style::Tuple,
..
}) if fields.len() == 1 => {
let ty_ident = base.ident;
quote!(
fn from_meta(__item: &::syn::Meta) -> ::darling::Result<Self> {
::darling::FromMeta::from_meta(__item)
.map_err(|e| e.with_span(&__item))
.map(#ty_ident)
}
)
}
Data::Struct(Fields {
style: Style::Tuple,
..
}) => {
panic!("Multi-field tuples are not supported");
}
Data::Struct(ref data) => {
let inits = data.fields.iter().map(Field::as_initializer);
let declare_errors = base.declare_errors();
let require_fields = base.require_fields();
let check_errors = base.check_errors();
let decls = base.local_declarations();
let core_loop = base.core_loop();
let default = base.fallback_decl();
let map = base.map_fn();
quote!(
fn from_list(__items: &[::syn::NestedMeta]) -> ::darling::Result<Self> {
#decls
#declare_errors
#core_loop
#require_fields
#check_errors
#default
::darling::export::Ok(Self {
#(#inits),*
}) #map
}
)
}
Data::Enum(ref variants) => {
let unit_arms = variants.iter().map(Variant::as_unit_match_arm);
let struct_arms = variants.iter().map(Variant::as_data_match_arm);
let unknown_variant_err = if !variants.is_empty() {
let names = variants.iter().map(Variant::as_name);
quote! {
unknown_field_with_alts(__other, &[#(#names),*])
}
} else {
quote! {
unknown_field(__other)
}
};
quote!(
fn from_list(__outer: &[::syn::NestedMeta]) -> ::darling::Result<Self> {
match __outer.len() {
0 => ::darling::export::Err(::darling::Error::too_few_items(1)),
1 => {
if let ::syn::NestedMeta::Meta(ref __nested) = __outer[0] {
match __nested.path().segments.iter().map(|s| s.ident.to_string()).collect::<Vec<String>>().join("::").as_ref() {
#(#struct_arms)*
__other => ::darling::export::Err(::darling::Error::#unknown_variant_err.with_span(__nested))
}
} else {
::darling::export::Err(::darling::Error::unsupported_format("literal"))
}
}
_ => ::darling::export::Err(::darling::Error::too_many_items(1)),
}
}
fn from_string(lit: &str) -> ::darling::Result<Self> {
match lit {
#(#unit_arms)*
__other => ::darling::export::Err(::darling::Error::unknown_value(__other))
}
}
)
}
};
self.wrap(impl_block, tokens);
}
}
impl<'a> OuterFromImpl<'a> for FromMetaImpl<'a> {
fn trait_path(&self) -> syn::Path {
path!(::darling::FromMeta)
}
fn base(&'a self) -> &'a TraitImpl<'a> {
&self.base
}
}