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
mod variant;
use crate::{
arguments::variant::Variant,
input::{item::Item, Input},
};
use proc_macro2::{Ident, Span};
use syn::{spanned::Spanned, Error, Expr, ExprArray, ExprLit, ExprPath, Lit, Path};
pub struct Arguments {
pub variants: Vec<Variant>,
pub storage: bool,
pub path: Option<Path>,
pub default: Ident,
pub derive: Vec<Path>,
}
impl Arguments {
pub fn new(input: Input) -> Result<Self, Error> {
let mut variants = Vec::new();
let mut storage = false;
let mut path = None;
let mut default = None;
let mut derive = Vec::new();
for item in input.into_iter() {
match item {
Item::Variant { name, label } => variants.push(Variant { name, label }),
Item::Optional { name, value } => match name.as_str() {
"storage" => match value {
Expr::Lit(ExprLit {
lit: Lit::Bool(bool),
..
}) => storage = bool.value,
_ => {
return Err(Error::new(
value.span(),
"Expected `storage` to be a `bool`",
));
}
},
"path" => match value {
Expr::Path(ExprPath { path: path_, .. }) => path = Some(path_),
_ => {
return Err(Error::new(value.span(), "Expected `path` to be a `Path`"));
}
},
"default" => match value {
Expr::Path(ExprPath { path, .. }) => {
if let Some(ident) = path.get_ident() {
default = Some(ident.clone());
} else {
return Err(Error::new(
path.span(),
"Expected `default` to be an `Ident`",
));
}
}
_ => {
return Err(Error::new(
value.span(),
"Expected `default` to be an `Ident`",
));
}
},
"derive" => match value {
Expr::Array(ExprArray {
elems: elements, ..
}) => {
for element in elements {
match element {
Expr::Path(ExprPath { path: path_, .. }) => {
derive.push(path_.clone())
}
_ => {
return Err(Error::new(
element.span(),
"Expected `derive` to be an array of `Path`",
));
}
}
}
}
_ => {
return Err(Error::new(
value.span(),
"Expected `derive` to be an array of `Path`",
));
}
},
_ => {
return Err(Error::new(
value.span(),
format!("Unknown parameter `{name}`"),
));
}
},
}
}
let default = default.unwrap_or(
variants
.first()
.ok_or(Error::new(
Span::call_site(),
"Expected at least one locale variant",
))?
.name
.clone(),
);
Ok(Self {
variants,
storage,
path,
default,
derive,
})
}
}