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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//! Additional helper functions for validating after parsing.
use crate Errors;
/// Appends an error if more than one given attribute is present.
///
/// `attrs` should provide an iterator of tuples containing the field name, and an [`Option`]
/// possibly containing the field value. If two or more are [`Some`], an error will be appended to
/// `errors`, with `prefix` prepended onto the names.
/// Appends an error if some attributes are present, but not all of them.
///
/// `attrs` should provide an iterator of tuples containing the field name, and an [`Option`]
/// possibly containing the field value. If at least one is [`Some`] and at least one is [`None`],
/// an error will be appended to `errors`, with `prefix` prepended onto the names.
;
=> ;
}
/// Appends an error if more than one given attribute is present, automatically casting and
/// stringifying field names.
///
/// Convenience macro for [`only_one`](fn@only_one). The first argument is a <code>&[str]</code>
/// prefix to prepend onto the names in the event of an error. The second argument is an
/// <code>&[Errors]</code> to add any errors into.
///
/// The rest of the arguments are either identifiers or 2-element tuples. Identifiers must be an
/// `Option<T>` and tuples must be `(&str, Option<&T>)`, where `&T` is castable to <code>&dyn
/// [syn::spanned::Spanned]</code>. Identifiers will automatically [`stringify`] the identifier
/// name to use in the error message, and so should used when the field name is the same as the
/// variable name. The tuple form can be used to specify a different field name from the name of
/// the variable. The identifier form is intended to make it easier to do validations by
/// destructuring a data type after it has been parsed.
///
/// # Example
///
/// ```
/// #[derive(Default)]
/// struct MyStruct {
/// my_bool: Option<syn::LitBool>,
/// path: Option<syn::Path>,
/// // #[deluxe(rename = "ty")]
/// field3: Option<syn::Type>,
/// }
/// let errors = deluxe_core::Errors::new();
/// let s = MyStruct::default();
///
/// // ... parsing omitted ...
///
/// let MyStruct { my_bool, path, field3 } = &s;
/// // only one of `my_bool`, `path`, `ty` is allowed
/// deluxe_core::only_one!("", &errors, my_bool, path, ("ty", field3.as_ref()));
/// # assert!(errors.is_empty());
/// ```
/// Appends an error if some attributes are present, but not all of them, automatically casting and
/// stringifying field names.
///
/// Convenience macro for [`all_or_none`](fn@all_or_none). The first argument is a
/// <code>&[str]</code> prefix to prepend onto the names in the event of an error. The second
/// argument is an <code>&[Errors]</code> to add any errors into.
///
/// The rest of the arguments are either identifiers or 2-element tuples. Identifiers must be an
/// `Option<T>` and tuples must be `(&str, Option<&T>)`, where `&T` is castable to <code>&dyn
/// [syn::spanned::Spanned]</code>. Identifiers will automatically [`stringify`] the identifier
/// name to use in the error message, and so should used when the field name is the same as the
/// variable name. The tuple form can be used to specify a different field name from the name of
/// the variable. The identifier form is intended to make it easier to do validations by
/// destructuring a data type after it has been parsed.
///
/// # Example
///
/// ```
/// #[derive(Default)]
/// struct MyStruct {
/// my_bool: Option<syn::LitBool>,
/// path: Option<syn::Path>,
/// // #[deluxe(rename = "ty")]
/// field3: Option<syn::Type>,
/// }
/// let errors = deluxe_core::Errors::new();
/// let s = MyStruct::default();
///
/// // ... parsing omitted ...
///
/// let MyStruct { my_bool, path, field3 } = &s;
/// // if any of `my_bool`, `path`, `ty` is present, then all must be present
/// deluxe_core::all_or_none!("", &errors, my_bool, path, ("ty", field3.as_ref()));
/// # assert!(errors.is_empty());
/// ```