xsd_parser/traits/
vec_helper.rs

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