1use roxmltree::{
2 Node,
3};
4use std::collections::btree_map::{
5 BTreeMap,
6 OccupiedEntry,
7};
8use std::ops::Range;
9
10use crate::{
11 Map,
12};
13
14use super::{
15 duplicate_element,
16 Id,
17 missing_attribute,
18 Once,
19 ParseError,
20};
21
22pub struct ParsingMap<Name, Value, Index> {
23 index: Index,
24 map: BTreeMap<Name, Parsing<Value, Index>>,
25}
26
27pub struct Parsing<Value, Index> {
28 index: Index,
29 name_range: Range<usize>,
30 value_range: Range<usize>,
31 value: Option<Value>,
32}
33
34pub struct ParsingEntry<'a, Name, Value, Index> {
35 entry: OccupiedEntry<'a, Name, Parsing<Value, Index>>,
36}
37
38pub struct ParsedMap<Name, Value, Index> {
39 names: BTreeMap<Name, Index>,
40 vec: Vec<ParsedEntry<Name, Value, Index>>,
41}
42
43#[derive(Clone)]
44pub struct ParsedEntry<Name, Value, Index> {
45 pub index: Index,
46 pub name: Name,
47 pub range: Range<usize>,
48 pub value: Value,
49}
50
51impl<Name: Ord, Value, Index: Id> ParsingMap<Name, Value, Index> {
52 pub fn new() -> Self {
53 ParsingMap {
54 map: BTreeMap::new(),
55 index: Index::zero(),
56 }
57 }
58
59 pub fn builtin(
60 &mut self,
61 name: Name,
62 range: Range<usize>,
63 value: Value,
64 ) {
65 self.map.insert(name, Parsing {
66 index: self.index.clone(),
67 name_range: range.clone(),
68 value_range: range,
69 value: Some(value),
70 });
71
72 self.index.succ();
73 }
74
75 pub fn insert<'input, 'a, E>(
84 &'a mut self,
85 name: Once<Name>,
86 element: &Node<'input, 'input>,
87 errors: &mut Vec<E>,
88 ) -> Option<ParsingEntry<'a, Name, Value, Index>>
89 where
90 E: From<ParseError>,
91 {
92 match name {
93 Once::Missing { name } => {
94 missing_attribute(name, element, errors);
95
96 None
97 }
98
99 Once::Failure { .. } =>
100 None,
101
102 Once::Success { value: name, value_range: name_range, .. } => {
103 use std::collections::btree_map::Entry::*;
104
105 match self.map.entry(name) {
106 Vacant(entry) => {
107 let entry = entry.insert_entry(Parsing {
108 index: self.index.clone(),
109 name_range,
110 value_range: element.range(),
111 value: None,
112 });
113
114 self.index.succ();
115
116 Some(ParsingEntry {
117 entry,
118 })
119 }
120
121 Occupied(entry) => {
122 let existing = entry.get();
123
124 duplicate_element(
125 element.tag_name().name(),
126 name_range,
127 existing.name_range.clone(),
128 errors,
129 );
130
131 None
132 }
133 }
134 }
135 }
136 }
137
138 pub fn insert_derived<'input, 'a, E>(
145 &'a mut self,
146 element_name: &str,
147 name: Name,
148 name_range: Range<usize>,
149 errors: &mut Vec<E>,
150 ) -> Option<ParsingEntry<'a, Name, Value, Index>>
151 where
152 E: From<ParseError>,
153 {
154 use std::collections::btree_map::Entry::*;
155
156 match self.map.entry(name) {
157 Vacant(entry) => {
158 let entry = entry.insert_entry(Parsing {
159 index: self.index.clone(),
160 name_range: name_range.clone(),
161 value_range: name_range,
162 value: None,
163 });
164
165 Some(ParsingEntry {
166 entry,
167 })
168 }
169
170 Occupied(entry) => {
171 let existing = entry.get();
172
173 duplicate_element(element_name, name_range, existing.name_range.clone(), errors);
174
175 None
176 }
177 }
178 }
179
180 pub fn collect(self) -> Option<ParsedMap<Name, Value, Index>>
185 where
186 Name: Clone,
187 {
188 let mut names = BTreeMap::new();
189 let mut vec = Vec::new();
190 let mut index = Index::zero();
191
192 for (name, parsing) in self.map {
193 if let Some(value) = parsing.value {
194 names.insert(name.clone(), index.clone());
195 vec.push(ParsedEntry {
196 index: index.clone(),
197 name: name,
198 range: parsing.value_range,
199 value,
200 });
201 index.succ();
202 } else {
203 return None;
204 }
205 }
206
207 Some(ParsedMap {
208 names,
209 vec,
210 })
211 }
212
213 pub fn collect_by_index(mut self)
218 -> Option<ParsedMap<Name, Value, Index>>
219 where
220 Index: Ord,
221 Name: Clone,
222 {
223 let mut indexes = BTreeMap::new();
224 let mut names = BTreeMap::new();
225 let mut vec = Vec::new();
226
227 for (name, parsing) in &self.map {
228 if let Some(_) = parsing.value {
229 indexes.insert(parsing.index.clone(), name.clone());
230 } else {
231 return None;
232 }
233 }
234
235 for (index, name) in indexes {
236 let (parsed_name, parsing) = self.map.remove_entry(&name).unwrap();
237 names.insert(name, index);
238 vec.push(ParsedEntry {
239 index: parsing.index,
240 name: parsed_name,
241 range: parsing.value_range,
242 value: parsing.value.unwrap(),
243 });
244 }
245
246 Some(ParsedMap {
247 names,
248 vec,
249 })
250 }
251
252 pub fn collect_by_key<Key, F>(mut self, key: F)
257 -> Option<ParsedMap<Name, Value, Index>>
258 where
259 Index: Ord,
260 Name: Clone,
261 Key: Ord,
262 F: Fn(&Value) -> Key,
263 {
264 let mut keys = BTreeMap::new();
265 let mut names = BTreeMap::new();
266 let mut vec = Vec::new();
267
268 for (name, parsing) in &self.map {
269 if let Some(value) = &parsing.value {
270 keys.insert(key(value), name.clone());
271 } else {
272 return None;
273 }
274 }
275
276 for (_key, name) in keys {
277 let (parsed_name, parsing) = self.map.remove_entry(&name).unwrap();
278 names.insert(name, parsing.index.clone());
279 vec.push(ParsedEntry {
280 index: parsing.index,
281 name: parsed_name,
282 range: parsing.value_range,
283 value: parsing.value.unwrap(),
284 });
285 }
286
287 Some(ParsedMap {
288 names,
289 vec,
290 })
291 }
292
293 pub fn collect_to_btree(self) -> Option<BTreeMap<Name, Value>>
298 where
299 Name: Clone,
300 {
301 let mut map = BTreeMap::new();
302
303 for (name, parsing) in self.map {
304 if let Some(value) = parsing.value {
305 map.insert(name.clone(), value);
306 } else {
307 return None;
308 }
309 }
310
311 Some(map)
312 }
313}
314
315impl<'a, Name: Ord, Value, Index: Clone> ParsingEntry<'a, Name, Value, Index> {
316 pub fn index(&self) -> Index {
317 self.entry.get().index.clone()
318 }
319
320 pub fn name(&self) -> &Name {
321 self.entry.key()
322 }
323
324 pub fn name_range(&self) -> Range<usize> {
325 self.entry.get().name_range.clone()
326 }
327
328 pub fn value(mut self, value: Value) {
329 self.entry.get_mut().value = Some(value);
330 }
331}
332
333impl<Name: Ord, Value, Index: Id> ParsedMap<Name, Value, Index> {
334 pub fn get<Find>(&self, name: &Find) -> Option<(Index, &Value)>
335 where
336 Name: std::borrow::Borrow<Find> + Ord,
337 Find: Ord + ?Sized,
338 {
339 if let Some(id) = self.names.get(name) {
340 let parsed = self.vec.get(id.index())
341 .expect("Exist by construction");
342 Some((id.clone(), &parsed.value))
343 } else {
344 None
345 }
346 }
347
348 pub fn get_id<Find>(&self, name: &Find) -> Option<Index>
349 where
350 Name: std::borrow::Borrow<Find> + Ord,
351 Find: Ord + ?Sized,
352 {
353 self.names.get(name).cloned()
354 }
355
356 pub fn get_parsed<Find>(&self, name: &Find) -> Option<(Index, &ParsedEntry<Name, Value, Index>)>
357 where
358 Name: std::borrow::Borrow<Find> + Ord,
359 Find: Ord + ?Sized,
360 {
361 if let Some(id) = self.names.get(name) {
362 let parsed = self.vec.get(id.index())
363 .expect("Exist by construction");
364 Some((id.clone(), parsed))
365 } else {
366 None
367 }
368 }
369
370 pub fn iter(&self) -> std::slice::Iter<'_, ParsedEntry<Name, Value, Index>> {
371 self.vec.iter()
372 }
373
374 pub fn map<V, With, E>(
375 &self,
376 with: With,
377 errors: &mut Vec<E>,
378 ) -> Option<Map<Name, V, Index>>
379 where
380 Name: Clone,
381 With: Fn(&ParsedEntry<Name, Value, Index>, &mut Vec<E>) -> Option<V>,
382 {
383 let mut vec = Vec::new();
384
385 for parsed in &self.vec {
386 if let Some(value) = with(parsed, errors) {
387 vec.push(value);
388 } else {
389 return None;
390 }
391 }
392
393 Some(Map {
394 names: self.names.clone(),
395 vec,
396 })
397 }
398
399 pub fn map_cx<V, With, C, E>(
400 &self,
401 with: With,
402 cx: &C,
403 errors: &mut Vec<E>,
404 ) -> Option<Map<Name, V, Index>>
405 where
406 Name: Clone,
407 With: Fn(&ParsedEntry<Name, Value, Index>, &C, &mut Vec<E>) -> Option<V>,
408 {
409 let mut vec = Vec::new();
410
411 for parsed in &self.vec {
412 if let Some(value) = with(parsed, cx, errors) {
413 vec.push(value);
414 } else {
415 return None;
416 }
417 }
418
419 Some(Map {
420 names: self.names.clone(),
421 vec,
422 })
423 }
424
425 pub fn map_cx2<V, With, C, D, E>(
426 &self,
427 with: With,
428 cx: &C,
429 dx: &D,
430 errors: &mut Vec<E>,
431 ) -> Option<Map<Name, V, Index>>
432 where
433 Name: Clone,
434 With: Fn(&ParsedEntry<Name, Value, Index>, &C, &D, &mut Vec<E>) -> Option<V>,
435 {
436 let mut vec = Vec::new();
437
438 for parsed in &self.vec {
439 if let Some(value) = with(parsed, cx, dx, errors) {
440 vec.push(value);
441 } else {
442 return None;
443 }
444 }
445
446 Some(Map {
447 names: self.names.clone(),
448 vec,
449 })
450 }
451
452 pub fn map_cx_mut<V, With, C, D, E>(
453 &self,
454 with: With,
455 cx: &C,
456 dx: &mut D,
457 errors: &mut Vec<E>,
458 ) -> Option<Map<Name, V, Index>>
459 where
460 Name: Clone,
461 With: Fn(&ParsedEntry<Name, Value, Index>, &C, &mut D, &mut Vec<E>) -> Option<V>,
462 {
463 let mut vec = Vec::new();
464
465 for parsed in &self.vec {
466 if let Some(value) = with(parsed, cx, dx, errors) {
467 vec.push(value);
468 } else {
469 return None;
470 }
471 }
472
473 Some(Map {
474 names: self.names.clone(),
475 vec,
476 })
477 }
478
479 pub fn map_mut<V, With, C, E>(
480 &self,
481 with: With,
482 cx: &mut C,
483 errors: &mut Vec<E>,
484 ) -> Option<Map<Name, V, Index>>
485 where
486 Name: Clone,
487 With: Fn(&ParsedEntry<Name, Value, Index>, &mut C, &mut Vec<E>) -> Option<V>,
488 {
489 let mut vec = Vec::new();
490
491 for parsed in &self.vec {
492 if let Some(value) = with(parsed, cx, errors) {
493 vec.push(value);
494 } else {
495 return None;
496 }
497 }
498
499 Some(Map {
500 names: self.names.clone(),
501 vec,
502 })
503 }
504}