serde_amqp/primitives/
map.rs

1use std::{hash::Hash, marker::PhantomData, ops::RangeBounds};
2
3use indexmap::{Equivalent, IndexMap};
4use serde::{de, ser::SerializeMap, Deserialize, Serialize};
5
6pub use indexmap::map::{Drain, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
7
8/// A wrapper around [`IndexMap`] with custom implementation of [`PartialEq`], [`Eq`],
9/// [`PartialOrd`], [`Ord`], [`Hash`], [`Serialize`], and [`Deserialize`].
10///
11/// Only a selected list of methods are re-exported for convenience.
12#[derive(Debug, Clone, Default)]
13pub struct OrderedMap<K, V>(IndexMap<K, V>);
14
15impl<K, V> From<IndexMap<K, V>> for OrderedMap<K, V> {
16    fn from(map: IndexMap<K, V>) -> Self {
17        Self(map)
18    }
19}
20
21impl<K, V> OrderedMap<K, V> {
22    /// Creates a new [`OrderedMap`]
23    pub fn new() -> Self {
24        Self(IndexMap::new())
25    }
26
27    /// Return the number of key-value pairs in the map.
28    ///
29    /// Calls [`IndexMap::len`] internally
30    pub fn len(&self) -> usize {
31        self.0.len()
32    }
33
34    /// Return an iterator over the key-value pairs of the map, in their order
35    ///
36    /// Calls [`IndexMap::iter`] internally
37    pub fn iter(&self) -> Iter<'_, K, V> {
38        self.0.iter()
39    }
40
41    /// Return an iterator over the key-value pairs of the map, in their order
42    ///
43    /// Calls [`IndexMap::iter_mut`] internally
44    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
45        self.0.iter_mut()
46    }
47
48    /// Get a reference to the inner [`IndexMap`]
49    ///
50    /// It is intentional to NOT implement the `AsRef<IndexMap>` trait to avoid potential
51    /// misuse
52    pub fn as_inner(&self) -> &IndexMap<K, V> {
53        &self.0
54    }
55
56    /// Get a mutable reference to the inner [`IndexMap`]
57    ///
58    /// It is intentional to NOT implement the `AsMut<IndexMap>` trait to avoid potential
59    /// misuse
60    pub fn as_inner_mut(&mut self) -> &mut IndexMap<K, V> {
61        &mut self.0
62    }
63
64    /// Consumes the wrapper and returns the inner [`IndexMap`]
65    pub fn into_inner(self) -> IndexMap<K, V> {
66        self.0
67    }
68
69    /// Returns true if the map contains no elements.
70    pub fn is_empty(&self) -> bool {
71        self.0.is_empty()
72    }
73
74    /// Return an owning iterator over the keys of the map, in their order
75    pub fn into_keys(self) -> IntoKeys<K, V> {
76        self.0.into_keys()
77    }
78
79    /// Return an iterator over the keys of the map, in their order
80    pub fn keys(&self) -> Keys<'_, K, V> {
81        self.0.keys()
82    }
83
84    /// Return an iterator over the values of the map, in their order
85    pub fn values(&self) -> Values<'_, K, V> {
86        self.0.values()
87    }
88
89    /// Return an iterator over mutable references to the values of the map, in their order
90    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
91        self.0.values_mut()
92    }
93
94    /// Return an owning iterator over the values of the map, in their order
95    pub fn into_values(self) -> IntoValues<K, V> {
96        self.0.into_values()
97    }
98
99    /// Remove all key-value pairs in the map, while preserving its capacity.
100    ///
101    /// Computes in O(n) time.
102    pub fn clear(&mut self) {
103        self.0.clear()
104    }
105
106    ///Clears the IndexMap in the given index range, returning those key-value pairs as a drain iterator.
107    ///
108    ///The range may be any type that implements `RangeBounds<usize>`, including all of the std::ops::Range* types, or even a tuple pair of Bound start and end values. To drain the map entirely, use RangeFull like map.drain(..).
109    ///
110    ///This shifts down all entries following the drained range to fill the gap, and keeps the allocated memory for reuse.
111    ///
112    ///Panics if the starting point is greater than the end point or if the end point is greater than the length of the map.
113    pub fn drain<R>(&mut self, range: R) -> Drain<'_, K, V>
114    where
115        R: RangeBounds<usize>,
116    {
117        self.0.drain(range)
118    }
119}
120
121impl<K, V> OrderedMap<K, V>
122where
123    K: Hash + Eq,
124{
125    /// Insert a key-value pair in the map.
126    ///
127    /// Calls [`IndexMap::insert`] internally
128    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
129        self.0.insert(key, value)
130    }
131
132    /// Calls [`IndexMap::get`] internally
133    pub fn get<Q>(&self, key: &Q) -> Option<&V>
134    where
135        Q: Hash + Equivalent<K> + ?Sized,
136    {
137        self.0.get(key)
138    }
139
140    /// Calls [`IndexMap::get_mut`] internally
141    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
142    where
143        Q: Hash + Equivalent<K> + ?Sized,
144    {
145        self.0.get_mut(key)
146    }
147
148    /// Calls [`IndexMap::swap_remove`] internally
149    pub fn swap_remove<Q>(&mut self, key: &Q) -> Option<V>
150    where
151        Q: Hash + Equivalent<K> + ?Sized,
152    {
153        self.0.swap_remove(key)
154    }
155
156    /// Calls [`IndexMap::shift_remove`] internally
157    pub fn shift_remove<Q>(&mut self, key: &Q) -> Option<V>
158    where
159        Q: Hash + Equivalent<K> + ?Sized,
160    {
161        self.0.shift_remove(key)
162    }
163
164    /// Calls [`IndexMap::swap_remove_entry`] internally
165    pub fn swap_remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
166    where
167        Q: Hash + Equivalent<K> + ?Sized,
168    {
169        self.0.swap_remove_entry(key)
170    }
171
172    /// Calls [`IndexMap::shift_remove_entry`] internally
173    pub fn shift_remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
174    where
175        Q: Hash + Equivalent<K> + ?Sized,
176    {
177        self.0.shift_remove_entry(key)
178    }
179
180    /// Return true if an equivalent to key exists in the map.
181    ///
182    /// Calls [`IndexMap::contains_key`] internally
183    pub fn contains_key<Q>(&self, key: &Q) -> bool
184    where
185        Q: Hash + Equivalent<K> + ?Sized,
186    {
187        self.0.contains_key(key)
188    }
189
190    /// Create a new map with capacity for n key-value pairs. (Does not allocate if n is zero.)
191    ///
192    /// Calls [`IndexMap::with_capacity`] internally
193    pub fn with_capacity(n: usize) -> Self {
194        Self(IndexMap::with_capacity(n))
195    }
196
197    /// Shrink the capacity of the map as much as possible.
198    ///
199    /// Calss [`IndexMap::shrink_to_fit`] internally
200    pub fn shrink_to_fit(&mut self) {
201        self.0.shrink_to_fit()
202    }
203}
204
205impl<K, V> Serialize for OrderedMap<K, V>
206where
207    K: Serialize + Eq + Hash,
208    V: Serialize,
209{
210    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
211    where
212        S: serde::Serializer,
213    {
214        let len = self.0.len();
215        let mut map = serializer.serialize_map(Some(len))?;
216        for (key, value) in self {
217            map.serialize_entry(key, value)?;
218        }
219        map.end()
220    }
221}
222
223struct Visitor<K, V> {
224    key_marker: PhantomData<K>,
225    value_marker: PhantomData<V>,
226}
227
228impl<'de, K, V> de::Visitor<'de> for Visitor<K, V>
229where
230    K: Deserialize<'de> + Hash + Eq,
231    V: Deserialize<'de>,
232{
233    type Value = OrderedMap<K, V>;
234
235    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
236        formatter.write_str("A sequence of map entries")
237    }
238
239    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
240    where
241        A: de::MapAccess<'de>,
242    {
243        let mut inner = IndexMap::new();
244        while let Some((key, value)) = map.next_entry()? {
245            inner.insert(key, value);
246        }
247        Ok(OrderedMap(inner))
248    }
249}
250
251impl<'de, K, V> Deserialize<'de> for OrderedMap<K, V>
252where
253    K: Deserialize<'de> + Eq + Hash,
254    V: Deserialize<'de>,
255{
256    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
257    where
258        D: serde::Deserializer<'de>,
259    {
260        deserializer.deserialize_map(Visitor::<K, V> {
261            key_marker: PhantomData,
262            value_marker: PhantomData,
263        })
264    }
265}
266
267impl<K, V> PartialEq for OrderedMap<K, V>
268where
269    K: PartialEq,
270    V: PartialEq,
271{
272    #[inline]
273    fn eq(&self, other: &Self) -> bool {
274        self.0.len() == other.0.len() && self.0.iter().zip(&other.0).all(|(a, b)| a == b)
275    }
276}
277
278impl<K, V> Eq for OrderedMap<K, V>
279where
280    K: Eq,
281    V: Eq,
282{
283}
284
285impl<K, V> PartialOrd for OrderedMap<K, V>
286where
287    K: PartialOrd,
288    V: PartialOrd,
289{
290    #[inline]
291    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
292        self.0.iter().partial_cmp(other.0.iter())
293    }
294}
295
296impl<K, V> Ord for OrderedMap<K, V>
297where
298    K: Ord,
299    V: Ord,
300{
301    #[inline]
302    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
303        self.0.iter().cmp(other.0.iter())
304    }
305}
306
307impl<K, V> Hash for OrderedMap<K, V>
308where
309    K: Hash,
310    V: Hash,
311{
312    #[inline]
313    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
314        state.write_usize(self.0.len());
315        for entry in &self.0 {
316            entry.hash(state)
317        }
318    }
319}
320
321impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
322    type Item = (&'a K, &'a V);
323
324    type IntoIter = indexmap::map::Iter<'a, K, V>;
325
326    #[inline]
327    fn into_iter(self) -> Self::IntoIter {
328        self.0.iter()
329    }
330}
331
332impl<'a, K, V> IntoIterator for &'a mut OrderedMap<K, V> {
333    type Item = (&'a K, &'a mut V);
334
335    type IntoIter = indexmap::map::IterMut<'a, K, V>;
336
337    #[inline]
338    fn into_iter(self) -> Self::IntoIter {
339        self.0.iter_mut()
340    }
341}
342
343impl<K, V> IntoIterator for OrderedMap<K, V> {
344    type Item = (K, V);
345
346    type IntoIter = indexmap::map::IntoIter<K, V>;
347
348    #[inline]
349    fn into_iter(self) -> Self::IntoIter {
350        self.0.into_iter()
351    }
352}
353
354impl<K, V> FromIterator<(K, V)> for OrderedMap<K, V>
355where
356    K: Hash + Eq,
357{
358    #[inline]
359    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
360        let index_map = IndexMap::from_iter(iter);
361        Self(index_map)
362    }
363}