xsd_parser/types/
helper.rs

1use std::ops::DerefMut;
2
3use super::{AttributeInfo, ElementInfo, Ident, VariantInfo};
4
5/// Helper trait that adds name information to the implementing object.
6pub trait WithIdent {
7    /// Returns the name of the object.
8    fn ident(&self) -> &Ident;
9}
10
11impl WithIdent for VariantInfo {
12    fn ident(&self) -> &Ident {
13        &self.ident
14    }
15}
16
17impl WithIdent for ElementInfo {
18    fn ident(&self) -> &Ident {
19        &self.ident
20    }
21}
22
23impl WithIdent for AttributeInfo {
24    fn ident(&self) -> &Ident {
25        &self.ident
26    }
27}
28
29/// Helper trait that implements additional methods for vectors.
30pub trait VecHelper {
31    /// Item stored in the vector.
32    type Item;
33
34    /// Try to find the object with the passed `ident` in the vector. If it was
35    /// not found `None` is returned.
36    fn find(&mut self, ident: Ident) -> Option<&mut Self::Item>;
37
38    /// Try to find the object with the passed `ident` in the vector. If it was
39    /// not found, a new one is created by invoking `f`.
40    ///
41    /// Returns a mutable reference either to the found or the newly created object.
42    fn find_or_insert<F>(&mut self, ident: Ident, f: F) -> &mut Self::Item
43    where
44        F: FnOnce(Ident) -> Self::Item;
45}
46
47impl<X, T> VecHelper for X
48where
49    X: DerefMut<Target = Vec<T>>,
50    T: WithIdent,
51{
52    type Item = T;
53
54    fn find(&mut self, ident: Ident) -> Option<&mut Self::Item> {
55        self.iter_mut().find(|x| x.ident() == &ident)
56    }
57
58    fn find_or_insert<F>(&mut self, ident: Ident, f: F) -> &mut Self::Item
59    where
60        F: FnOnce(Ident) -> Self::Item,
61    {
62        let vec = &mut **self;
63
64        if let Some(i) = vec.iter().position(|x| x.ident() == &ident) {
65            &mut vec[i]
66        } else {
67            vec.push(f(ident));
68
69            vec.last_mut().unwrap()
70        }
71    }
72}