tini/ordered_hashmap.rs
1//! Ordered Hashmap
2//!
3//! Needs to iterate over items in predictable order
4//! e.g. for save ini sections and items in the same order as loaded or added
5
6use std::borrow::Borrow;
7use std::collections::hash_map::{self, Entry};
8use std::collections::HashMap;
9use std::hash::Hash;
10use std::iter::FromIterator;
11use std::iter::IntoIterator;
12
13/// Ordered hashmap built on top of std::collections::HashMap
14/// Keys are stored in the field `keys` in the order they were added
15#[derive(Debug)]
16pub struct OrderedHashMap<K, V> {
17 #[doc(hidden)]
18 base: HashMap<K, V>,
19 keys: Vec<K>,
20}
21
22impl<K, V> OrderedHashMap<K, V>
23where
24 K: Eq + Hash + Clone,
25{
26 /// Creates an empty `OrderedHashMap`.
27 ///
28 /// # Examples
29 ///
30 /// ```ignore
31 /// let mut map: OrderedHashMap<&str, i32> = HashMap::new();
32 /// ```
33 pub fn new() -> OrderedHashMap<K, V> {
34 OrderedHashMap { base: HashMap::<K, V>::new(), keys: Vec::<K>::new() }
35 }
36
37 /// Returns a reference to the value corresponding to the key.
38 ///
39 /// The key may be any borrowed form of the map's key type, but
40 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
41 /// the key type.
42 ///
43 /// # Examples
44 ///
45 /// ```ignore
46 /// let mut map = OrderedHashMap::new();
47 /// map.insert(1, "a");
48 /// assert_eq!(map.get(&1), Some(&"a"));
49 /// assert_eq!(map.get(&2), None);
50 /// ```
51 pub fn get<Q>(&self, k: &Q) -> Option<&V>
52 where
53 K: Borrow<Q>,
54 Q: Hash + Eq + ?Sized,
55 {
56 self.base.get(k)
57 }
58
59 /// Returns a mutable reference to the value corresponding to the key.
60 ///
61 /// The key may be any borrowed form of the map's key type, but
62 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
63 /// the key type.
64 ///
65 /// # Examples
66 ///
67 /// ```ignore
68 /// use ordered_hashmap::OrderedHashMap;
69 ///
70 /// let mut map = OrderedHashMap::new();
71 /// map.insert(1, "a");
72 /// if let Some(x) = map.get_mut(&1) {
73 /// *x = "b";
74 /// }
75 /// assert_eq!(map[&1], "b");
76 /// ```
77 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
78 where
79 K: Borrow<Q>,
80 Q: Hash + Eq + ?Sized,
81 {
82 self.base.get_mut(k)
83 }
84
85 pub fn contains_key<Q>(&self, k: &Q) -> bool
86 where
87 K: Borrow<Q>,
88 Q: Hash + Eq + ?Sized,
89 {
90 self.base.contains_key(k)
91 }
92
93 /// Inserts a key-value pair into the map.
94 ///
95 /// If the map did not have this key present, [`None`] is returned.
96 ///
97 /// If the map did have this key present, the value is updated, and the old
98 /// value is returned. The key is not updated, though; this matters for
99 /// types that can be `==` without being identical.
100 ///
101 /// # Examples
102 ///
103 /// ```ignore
104 /// let mut map = OrderedHashMap::new();
105 /// assert_eq!(map.insert(37, "a"), None);
106 /// assert_eq!(map.is_empty(), false);
107 ///
108 /// map.insert(37, "b");
109 /// assert_eq!(map.insert(37, "c"), Some("b"));
110 /// assert_eq!(map[&37], "c");
111 /// ```
112 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
113 if !self.base.contains_key(&k) {
114 self.keys.push(k.clone());
115 }
116 self.base.insert(k, v)
117 }
118
119 /// Removes a key from the map, returning the value at the key if the key
120 /// was previously in the map.
121 ///
122 /// # Examples
123 ///
124 /// ```ignore
125 /// let mut map = OrderedHashMap::new();
126 /// map.insert(1, "a");
127 /// assert_eq!(map.remove(&1), Some("a"));
128 /// assert_eq!(map.remove(&1), None);
129 /// ```
130 pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
131 where
132 K: Borrow<Q> + PartialEq<Q>,
133 Q: Hash + Eq + ?Sized,
134 {
135 match self.keys.iter().position(|x| x == k) {
136 Some(index) => {
137 self.keys.swap_remove(index);
138 self.base.remove(k)
139 }
140 None => None,
141 }
142 }
143
144 /// An iterator visiting all key-value pairs in the order they were added.
145 /// The iterator element type is `(&'a K, &'a V)`.
146 ///
147 /// # Examples
148 ///
149 /// ```ignore
150 /// let mut map = OrderedHashMap::new();
151 /// map.insert("a", 1);
152 /// map.insert("b", 2);
153 /// map.insert("c", 3);
154 ///
155 /// for (key, val) in map.iter() {
156 /// println!("key: {} val: {}", key, val);
157 /// }
158 /// ```
159 pub fn iter(&self) -> Iter<'_, K, V> {
160 Iter { base: &self.base, keys_iterator: self.keys.iter() }
161 }
162
163 /// An iterator visiting all key-value pairs in the order they were added,
164 /// with mutable references to the values.
165 /// The iterator element type is `(&'a K, &'a mut V)`.
166 ///
167 /// # Examples
168 ///
169 /// ```ignore
170 /// let mut map = OrderedHashMap::new();
171 /// map.insert("a", 1);
172 /// map.insert("b", 2);
173 /// map.insert("c", 3);
174 ///
175 /// // Update all values
176 /// for (_, val) in map.iter_mut() {
177 /// *val *= 2;
178 /// }
179 ///
180 /// for (key, val) in &map {
181 /// println!("key: {} val: {}", key, val);
182 /// }
183 /// ```
184 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
185 self.base.iter_mut()
186 }
187
188 /// An iterator visiting all keys in the order they were added.
189 /// The iterator element type is `&'a K`.
190 ///
191 /// # Examples
192 ///
193 /// ```ignore
194 /// let mut map = OrderedHashMap::new();
195 /// map.insert("a", 1);
196 /// map.insert("b", 2);
197 /// map.insert("c", 3);
198 ///
199 /// for key in map.keys() {
200 /// println!("{}", key);
201 /// }
202 /// ```
203 pub fn keys(&self) -> std::slice::Iter<K> {
204 self.keys.iter()
205 }
206
207 /// Gets the given key's corresponding entry in the map for in-place manipulation.
208 ///
209 /// # Examples
210 ///
211 /// ```ignore
212 /// let mut letters = OrderedHashMap::new();
213 ///
214 /// for ch in "a short treatise on fungi".chars() {
215 /// let counter = letters.entry(ch).or_insert(0);
216 /// *counter += 1;
217 /// }
218 ///
219 /// assert_eq!(letters[&'s'], 2);
220 /// assert_eq!(letters[&'t'], 3);
221 /// assert_eq!(letters[&'u'], 1);
222 /// assert_eq!(letters.get(&'y'), None);
223 /// ```
224 pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
225 if !self.base.contains_key(&key) {
226 self.keys.push(key.clone());
227 }
228 self.base.entry(key)
229 }
230}
231
232impl<K, V> Default for OrderedHashMap<K, V>
233where
234 K: Eq + Hash + Clone,
235{
236 fn default() -> Self {
237 Self::new()
238 }
239}
240
241impl<'a, K, V> IntoIterator for &'a OrderedHashMap<K, V>
242where
243 K: Eq + Hash,
244{
245 type Item = (&'a K, &'a V);
246 type IntoIter = Iter<'a, K, V>;
247
248 fn into_iter(self) -> Self::IntoIter {
249 Iter { base: &self.base, keys_iterator: self.keys.iter() }
250 }
251}
252
253impl<K, V> FromIterator<(K, V)> for OrderedHashMap<K, V>
254where
255 K: Eq + Hash + Clone,
256{
257 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
258 let mut map = OrderedHashMap::new();
259
260 for (k, v) in iter {
261 map.insert(k, v);
262 }
263
264 map
265 }
266}
267/// An iterator over the entries of a `OrderedHashMap`.
268///
269/// This `struct` is created by the `iter` method on `OrderedHashMap`.
270///
271/// # Example
272///
273/// ```ignore
274/// let mut map = OrderedHashMap::new();
275/// map.insert("a", 1);
276/// let iter = map.iter();
277/// ```
278pub struct Iter<'a, K, V> {
279 #[doc(hidden)]
280 base: &'a HashMap<K, V>,
281 keys_iterator: std::slice::Iter<'a, K>,
282}
283
284impl<'a, K, V> Iterator for Iter<'a, K, V>
285where
286 K: Eq + Hash,
287{
288 type Item = (&'a K, &'a V);
289 fn next(&mut self) -> Option<Self::Item> {
290 match self.keys_iterator.next() {
291 Some(k) => self.base.get_key_value(&k),
292 None => None,
293 }
294 }
295}
296
297/// An owning iterator over the entries of a `OrderedHashMap`.
298///
299/// This `struct` is created by the `into_iter` method on `OrderedHashMap`
300/// (provided by the `IntoIterator` trait)
301///
302/// # Example
303///
304/// ```ignore
305/// let mut map = OrderedHashMap::new();
306/// map.insert("a", 1);
307/// let iter = map.into_iter();
308/// ```
309pub struct IntoIter<K, V> {
310 #[doc(hidden)]
311 base: HashMap<K, V>,
312 keys_iterator: std::vec::IntoIter<K>,
313}
314
315impl<K, V> Iterator for IntoIter<K, V>
316where
317 K: Eq + Hash,
318{
319 type Item = (K, V);
320 fn next(&mut self) -> Option<Self::Item> {
321 match self.keys_iterator.next() {
322 Some(k) => self.base.remove_entry(&k),
323 None => None,
324 }
325 }
326}
327
328/// A mutable iterator over the entries of a `OrderedHashMap`.
329/// Note that it iterates in arbitrary order.
330pub type IterMut<'a, K, V> = hash_map::IterMut<'a, K, V>;
331
332#[cfg(test)]
333mod library_test {
334 use super::*;
335
336 #[test]
337 fn get() {
338 let mut map = OrderedHashMap::new();
339 map.insert("a", 1);
340 assert_eq!(map.get("a"), Some(&1));
341 assert_eq!(map.get("b"), None);
342 }
343}