xsd_parser/xml/
namespaces.rs

1use std::borrow::{Borrow, Cow};
2use std::collections::HashMap;
3use std::fmt::{Debug, Formatter, Result as FmtResult};
4use std::ops::{Deref, DerefMut};
5use std::sync::Arc;
6
7use quick_xml::name::Namespace;
8
9use crate::models::format_utf8_slice;
10
11/// Represents a list of namespaces.
12#[derive(Default, Debug, Clone, Eq, PartialEq)]
13pub struct Namespaces<'a>(pub HashMap<Key<'a>, Value<'a>>);
14
15impl Namespaces<'_> {
16    /// Create a new [`Namespaces`] instance.
17    #[must_use]
18    pub fn new() -> Self {
19        Self::default()
20    }
21}
22
23impl<'a> Deref for Namespaces<'a> {
24    type Target = HashMap<Key<'a>, Value<'a>>;
25
26    fn deref(&self) -> &Self::Target {
27        &self.0
28    }
29}
30
31impl DerefMut for Namespaces<'_> {
32    fn deref_mut(&mut self) -> &mut Self::Target {
33        &mut self.0
34    }
35}
36
37impl<'a, K, V> FromIterator<(K, V)> for Namespaces<'a>
38where
39    K: Into<Cow<'a, [u8]>>,
40    V: Into<Cow<'a, [u8]>>,
41{
42    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
43        let mut namespaces = Namespaces::default();
44
45        for (k, v) in iter {
46            let key = Key(k.into());
47            let value = Value(v.into());
48
49            namespaces.insert(key, value);
50        }
51
52        namespaces
53    }
54}
55
56/// Wrapper type that is used as key for the [`Namespaces`] map.
57#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
58pub struct Key<'a>(pub Cow<'a, [u8]>);
59
60impl Deref for Key<'_> {
61    type Target = [u8];
62
63    fn deref(&self) -> &Self::Target {
64        &self.0
65    }
66}
67
68impl Debug for Key<'_> {
69    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
70        write!(f, "Key(\"")?;
71        format_utf8_slice(&self.0, f)?;
72        write!(f, "\")")?;
73
74        Ok(())
75    }
76}
77
78impl AsRef<[u8]> for Key<'_> {
79    fn as_ref(&self) -> &[u8] {
80        &self.0
81    }
82}
83
84impl Borrow<[u8]> for Key<'_> {
85    fn borrow(&self) -> &[u8] {
86        &self.0
87    }
88}
89
90/// Wrapper type that is used as value for the [`Namespaces`] map.
91#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
92pub struct Value<'a>(pub Cow<'a, [u8]>);
93
94impl Value<'_> {
95    /// Get the namespace as [`Namespace`].
96    #[inline]
97    #[must_use]
98    pub fn namespace(&self) -> Namespace<'_> {
99        Namespace(&self.0)
100    }
101}
102
103impl Debug for Value<'_> {
104    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
105        write!(f, "Value(\"")?;
106        format_utf8_slice(&self.0, f)?;
107        write!(f, "\")")?;
108
109        Ok(())
110    }
111}
112
113impl AsRef<[u8]> for Value<'_> {
114    fn as_ref(&self) -> &[u8] {
115        &self.0
116    }
117}
118
119impl Borrow<[u8]> for Value<'_> {
120    fn borrow(&self) -> &[u8] {
121        &self.0
122    }
123}
124
125/// Represents a shared list of namespaces.
126///
127/// This is useful to not store the same map again and again. Is uses an [`Arc`]
128/// under the hood, to maintain a reference to a shared list. If the list needs
129/// to be manipulated, a copy is created (like using [`Cow`]).
130#[derive(Default, Clone, Eq, PartialEq)]
131pub struct NamespacesShared<'a>(pub Arc<Namespaces<'a>>);
132
133impl<'a> NamespacesShared<'a> {
134    /// Create a new [`NamespacesShared`] instance from the passed `namespaces`.
135    #[must_use]
136    pub fn new(namespaces: Namespaces<'a>) -> Self {
137        Self(Arc::new(namespaces))
138    }
139
140    /// Create a new cloned copy of this shared list.
141    #[must_use]
142    pub fn to_owned(&self) -> Namespaces<'a> {
143        (*self.0).clone()
144    }
145
146    /// Convert this shared list into a unique list.
147    ///
148    /// This will clone the underlying [`Namespaces`] object if this shared list
149    /// is owned more then once.
150    #[must_use]
151    pub fn into_owned(self) -> Namespaces<'a> {
152        Arc::try_unwrap(self.0).unwrap_or_else(|x| (*x).clone())
153    }
154}
155
156impl<'a> Deref for NamespacesShared<'a> {
157    type Target = Namespaces<'a>;
158
159    fn deref(&self) -> &Self::Target {
160        &self.0
161    }
162}
163
164impl DerefMut for NamespacesShared<'_> {
165    fn deref_mut(&mut self) -> &mut Self::Target {
166        Arc::make_mut(&mut self.0)
167    }
168}
169
170impl Debug for NamespacesShared<'_> {
171    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
172        self.0.fmt(f)
173    }
174}