xsd_parser/
traits.rs

1use std::ops::DerefMut;
2
3use crate::models::{
4    meta::{AttributeMeta, ElementMeta, EnumerationMetaVariant},
5    Ident,
6};
7
8/// Trait that is used to get the [`Any`](core::any::Any) trait for a specific type.
9pub trait AsAny: core::any::Any {
10    /// Get a reference to the current object as [`Any`](core::any::Any).
11    fn as_any(&self) -> &dyn core::any::Any;
12
13    /// Get a mutable reference to the current object as [`Any`](core::any::Any).
14    fn as_any_mut(&mut self) -> &mut dyn core::any::Any;
15}
16
17impl<X: 'static> AsAny for X {
18    fn as_any(&self) -> &dyn core::any::Any {
19        self
20    }
21
22    fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
23        self
24    }
25}
26
27/// Trait that adds namespace information to a type.
28pub trait WithNamespace {
29    /// The default namespace prefix for this type.
30    fn prefix() -> Option<&'static str>;
31
32    /// The namespace for this type.
33    fn namespace() -> Option<&'static str>;
34}
35
36/// Helper trait that implements additional methods for vectors.
37pub trait VecHelper {
38    /// Item stored in the vector.
39    type Item;
40
41    /// Try to find the object with the passed `ident` in the vector. If it was
42    /// not found `None` is returned.
43    fn find(&mut self, ident: Ident) -> Option<&mut Self::Item>;
44
45    /// Try to find the object with the passed `ident` in the vector. If it was
46    /// not found, a new one is created by invoking `f`.
47    ///
48    /// Returns a mutable reference either to the found or the newly created object.
49    fn find_or_insert<F>(&mut self, ident: Ident, f: F) -> &mut Self::Item
50    where
51        F: FnOnce(Ident) -> Self::Item;
52}
53
54impl<X, T> VecHelper for X
55where
56    X: DerefMut<Target = Vec<T>>,
57    T: WithIdent,
58{
59    type Item = T;
60
61    fn find(&mut self, ident: Ident) -> Option<&mut Self::Item> {
62        self.iter_mut().find(|x| x.ident() == &ident)
63    }
64
65    fn find_or_insert<F>(&mut self, ident: Ident, f: F) -> &mut Self::Item
66    where
67        F: FnOnce(Ident) -> Self::Item,
68    {
69        let vec = &mut **self;
70
71        if let Some(i) = vec.iter().position(|x| x.ident() == &ident) {
72            &mut vec[i]
73        } else {
74            vec.push(f(ident));
75
76            vec.last_mut().unwrap()
77        }
78    }
79}
80
81/// Helper trait that adds name information to the implementing object.
82pub trait WithIdent {
83    /// Returns the name of the object.
84    fn ident(&self) -> &Ident;
85}
86
87impl WithIdent for EnumerationMetaVariant {
88    fn ident(&self) -> &Ident {
89        &self.ident
90    }
91}
92
93impl WithIdent for ElementMeta {
94    fn ident(&self) -> &Ident {
95        &self.ident
96    }
97}
98
99impl WithIdent for AttributeMeta {
100    fn ident(&self) -> &Ident {
101        &self.ident
102    }
103}