1use std::ops::DerefMut;
2
3use crate::models::{
4    meta::{AttributeMeta, ElementMeta, EnumerationMetaVariant},
5    Ident,
6};
7
8pub trait AsAny: core::any::Any {
10    fn as_any(&self) -> &dyn core::any::Any;
12
13    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
27pub trait WithNamespace {
29    fn prefix() -> Option<&'static str>;
31
32    fn namespace() -> Option<&'static str>;
34}
35
36pub trait VecHelper {
38    type Item;
40
41    fn find(&mut self, ident: Ident) -> Option<&mut Self::Item>;
44
45    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
81pub trait WithIdent {
83    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}