1use roxmltree::{
2 Attribute,
3 Node,
4};
5use std::ops::Range;
6
7use super::{
8 missing_attribute,
9 missing_element,
10 Parsed,
11 ParseError,
12};
13
14pub enum Once<T> {
15 Missing {
16 name: &'static str,
17 },
18 Failure {
19 name_range: Range<usize>,
20 value_range: Range<usize>,
21 },
22 Success {
23 name_range: Range<usize>,
24 value_range: Range<usize>,
25 value: T,
26 },
27}
28
29impl<T> Once<T> {
30 pub fn new(name: &'static str) -> Self {
31 Once::Missing {
32 name,
33 }
34 }
35
36 pub fn attribute_failure<'input>(
37 &mut self,
38 attribute: Attribute<'input, 'input>,
39 ) {
40 *self = Once::Failure {
41 name_range: attribute.range_qname(),
42 value_range: attribute.range_value(),
43 };
44 }
45
46 pub fn attribute_success<'input>(
47 &mut self,
48 attribute: Attribute<'input, 'input>,
49 value: T,
50 ) {
51 *self = Once::Success {
52 name_range: attribute.range_qname(),
53 value_range: attribute.range_value(),
54 value,
55 }
56 }
57
58 pub fn default(self, default: T) -> T {
59 match self {
60 Once::Success { value, .. } =>
61 value,
62
63 _ =>
64 default,
65 }
66 }
67
68 pub fn default_with<W>(self, with: W) -> T
69 where
70 W: FnOnce() -> T,
71 {
72 match self {
73 Once::Success { value, .. } =>
74 value,
75
76 _ =>
77 with(),
78 }
79 }
80
81 pub fn element_failure<'input>(
82 &mut self,
83 element: Node<'input, 'input>,
84 ) {
85 *self = Once::Failure {
86 name_range: element.range(),
87 value_range: element.range(),
88 };
89 }
90
91 pub fn element_parsed_success<'input>(
92 &mut self,
93 element: Node<'input, 'input>,
94 parsed: Parsed<T>,
95 ) {
96 *self = Once::Success {
97 name_range: element.range(),
98 value_range: parsed.range,
99 value: parsed.value,
100 }
101 }
102
103 pub fn element_success<'input>(
104 &mut self,
105 element: Node<'input, 'input>,
106 value: T,
107 ) {
108 *self = Once::Success {
109 name_range: element.range(),
110 value_range: element.range(),
111 value,
112 }
113 }
114
115 pub fn exist(&self) -> bool {
116 match self {
117 Once::Success { .. } |
118 Once::Failure { .. } =>
119 true,
120
121 Once::Missing { .. } =>
122 false,
123 }
124 }
125
126 pub fn exist_value(self) -> Option<Option<T>> {
127 match self {
128 Once::Success { value, .. } =>
129 Some(Some(value)),
130
131 Once::Failure { .. } =>
132 Some(None),
133
134 Once::Missing { .. } =>
135 None,
136 }
137 }
138
139 pub fn optional(self) -> Option<Option<T>> {
140 match self {
141 Once::Success { value, .. } =>
142 Some(Some(value)),
143
144 Once::Failure { .. } =>
145 None,
146
147 Once::Missing { .. } =>
148 Some(None),
149 }
150 }
151
152 pub fn optional_parsed(self) -> Option<Option<Parsed<T>>> {
153 match self {
154 Once::Success { value, value_range, .. } =>
155 Some(Some(Parsed {
156 range: value_range,
157 value,
158 })),
159
160 Once::Failure { .. } =>
161 None,
162
163 Once::Missing { .. } =>
164 Some(None),
165 }
166 }
167
168 pub fn required_attribute<'input, E>(
169 self,
170 parent: &Node<'input, 'input>,
171 errors: &mut Vec<E>,
172 ) -> Option<T>
173 where
174 E: From<ParseError>,
175 {
176 match self {
177 Once::Success { value, .. } =>
178 Some(value),
179
180 Once::Failure { .. } =>
181 None,
182
183 Once::Missing { name } => {
184 missing_attribute(name, parent, errors);
185
186 None
187 }
188 }
189 }
190
191 pub fn required_element<'input, E>(
195 self,
196 parent: &Node<'input, 'input>,
197 errors: &mut Vec<E>,
198 ) -> Option<T>
199 where
200 E: From<ParseError>,
201 {
202 match self {
203 Once::Success { value, .. } =>
204 Some(value),
205
206 Once::Failure { .. } =>
207 None,
208
209 Once::Missing { name } => {
210 missing_element(name, parent, errors);
211
212 None
213 }
214 }
215 }
216
217 pub fn required_parsed_attribute<'input, E>(
218 self,
219 parent: &Node<'input, 'input>,
220 errors: &mut Vec<E>,
221 ) -> Option<Parsed<T>>
222 where
223 E: From<ParseError>,
224 {
225 match self {
226 Once::Success { value, value_range, .. } =>
227 Some(Parsed {
228 range: value_range,
229 value,
230 }),
231
232 Once::Failure { .. } =>
233 None,
234
235 Once::Missing { name } => {
236 missing_attribute(name, parent, errors);
237
238 None
239 }
240 }
241 }
242
243 pub fn success_name_range(self) -> Option<Range<usize>> {
244 match self {
245 Once::Success { name_range, .. } =>
246 Some(name_range),
247
248 _ =>
249 None,
250 }
251 }
252
253 pub fn take(&mut self) -> Self {
254 std::mem::replace(self, Once::Missing { name: "Once::take" })
255 }
256}
257
258impl Once<bool> {
259 pub fn name_range_if_true(self) -> Option<Range<usize>> {
260 match self {
261 Once::Success { value: true, name_range, .. } =>
262 Some(name_range),
263
264 _ =>
265 None,
266 }
267 }
268
269 pub fn required_yes_attribute<'input, E>(
270 self,
271 parent: &Node<'input, 'input>,
272 errors: &mut Vec<E>,
273 ) -> bool
274 where
275 E: From<ParseError>,
276 {
277 match self {
278 Once::Success { value: true, .. } =>
279 true,
280
281 Once::Success { value: false, value_range, .. } => {
282 errors.push(ParseError::YesAttribute {
283 value: value_range.into(),
284 }.into());
285
286 false
287 }
288
289 Once::Failure { .. } =>
290 false,
291
292 Once::Missing { name } => {
293 missing_attribute(name, parent, errors);
294
295 false
296 }
297 }
298 }
299}