Skip to main content

jsonc_parser/
map.rs

1#[cfg(not(feature = "preserve_order"))]
2use std::borrow::Borrow;
3use std::hash::Hash;
4
5// the concrete backing map, selected by the enabled cargo features
6#[cfg(all(not(feature = "preserve_order"), not(feature = "fast_hash")))]
7type MapInner<K, V> = std::collections::HashMap<K, V>;
8#[cfg(all(not(feature = "preserve_order"), feature = "fast_hash"))]
9type MapInner<K, V> = std::collections::HashMap<K, V, rustc_hash::FxBuildHasher>;
10#[cfg(all(feature = "preserve_order", not(feature = "fast_hash")))]
11type MapInner<K, V> = indexmap::IndexMap<K, V>;
12#[cfg(all(feature = "preserve_order", feature = "fast_hash"))]
13type MapInner<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
14
15// backend-specific iterator and entry types, re-exported so the return types of
16// `Map`'s methods can be named
17#[cfg(not(feature = "preserve_order"))]
18pub use std::collections::hash_map::Entry;
19#[cfg(not(feature = "preserve_order"))]
20pub use std::collections::hash_map::IntoIter;
21#[cfg(not(feature = "preserve_order"))]
22pub use std::collections::hash_map::IntoKeys;
23#[cfg(not(feature = "preserve_order"))]
24pub use std::collections::hash_map::IntoValues;
25#[cfg(not(feature = "preserve_order"))]
26pub use std::collections::hash_map::Iter;
27#[cfg(not(feature = "preserve_order"))]
28pub use std::collections::hash_map::IterMut;
29#[cfg(not(feature = "preserve_order"))]
30pub use std::collections::hash_map::Keys;
31#[cfg(not(feature = "preserve_order"))]
32pub use std::collections::hash_map::Values;
33#[cfg(not(feature = "preserve_order"))]
34pub use std::collections::hash_map::ValuesMut;
35
36#[cfg(feature = "preserve_order")]
37pub use indexmap::map::Entry;
38#[cfg(feature = "preserve_order")]
39pub use indexmap::map::IntoIter;
40#[cfg(feature = "preserve_order")]
41pub use indexmap::map::IntoKeys;
42#[cfg(feature = "preserve_order")]
43pub use indexmap::map::IntoValues;
44#[cfg(feature = "preserve_order")]
45pub use indexmap::map::Iter;
46#[cfg(feature = "preserve_order")]
47pub use indexmap::map::IterMut;
48#[cfg(feature = "preserve_order")]
49pub use indexmap::map::Keys;
50#[cfg(feature = "preserve_order")]
51pub use indexmap::map::Values;
52#[cfg(feature = "preserve_order")]
53pub use indexmap::map::ValuesMut;
54
55/// The map used to store the properties of a [`JsonObject`](crate::JsonObject).
56///
57/// The backing implementation and hasher are selected by the `preserve_order`
58/// and `fast_hash` cargo features, but this type exposes the same API
59/// regardless of which are enabled. It's meant to be a drop-in replacement for
60/// the standard library's `HashMap`.
61pub struct Map<K, V>(MapInner<K, V>);
62
63impl<K, V> Map<K, V> {
64  /// Creates an empty map.
65  pub fn new() -> Self {
66    Map(MapInner::default())
67  }
68
69  /// Creates an empty map with at least the specified capacity.
70  pub fn with_capacity(capacity: usize) -> Self {
71    Map(MapInner::with_capacity_and_hasher(capacity, Default::default()))
72  }
73
74  /// Gets the number of entries.
75  pub fn len(&self) -> usize {
76    self.0.len()
77  }
78
79  /// Gets if there are no entries.
80  pub fn is_empty(&self) -> bool {
81    self.0.is_empty()
82  }
83
84  /// Gets the number of entries the map can hold without reallocating.
85  pub fn capacity(&self) -> usize {
86    self.0.capacity()
87  }
88
89  /// Removes all entries.
90  pub fn clear(&mut self) {
91    self.0.clear();
92  }
93
94  /// Iterates over the entries.
95  pub fn iter(&self) -> Iter<'_, K, V> {
96    self.0.iter()
97  }
98
99  /// Iterates over the entries with mutable references to the values.
100  pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
101    self.0.iter_mut()
102  }
103
104  /// Iterates over the keys.
105  pub fn keys(&self) -> Keys<'_, K, V> {
106    self.0.keys()
107  }
108
109  /// Iterates over the values.
110  pub fn values(&self) -> Values<'_, K, V> {
111    self.0.values()
112  }
113
114  /// Iterates over mutable references to the values.
115  pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
116    self.0.values_mut()
117  }
118
119  /// Consumes the map, iterating over its keys.
120  pub fn into_keys(self) -> IntoKeys<K, V> {
121    self.0.into_keys()
122  }
123
124  /// Consumes the map, iterating over its values.
125  pub fn into_values(self) -> IntoValues<K, V> {
126    self.0.into_values()
127  }
128}
129
130impl<K: Hash + Eq, V> Map<K, V> {
131  /// Inserts an entry, returning the previous value for the key if it existed.
132  pub fn insert(&mut self, key: K, value: V) -> Option<V> {
133    self.0.insert(key, value)
134  }
135
136  /// Gets the entry for the given key for in-place manipulation.
137  pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
138    self.0.entry(key)
139  }
140
141  /// Reserves capacity for at least `additional` more entries.
142  pub fn reserve(&mut self, additional: usize) {
143    self.0.reserve(additional);
144  }
145
146  /// Retains only the entries for which the predicate returns `true`.
147  pub fn retain<F: FnMut(&K, &mut V) -> bool>(&mut self, f: F) {
148    self.0.retain(f);
149  }
150}
151
152#[cfg(not(feature = "preserve_order"))]
153impl<K: Hash + Eq, V> Map<K, V> {
154  /// Gets a reference to the value for the given key.
155  pub fn get<Q>(&self, key: &Q) -> Option<&V>
156  where
157    K: Borrow<Q>,
158    Q: Hash + Eq + ?Sized,
159  {
160    self.0.get(key)
161  }
162
163  /// Gets a mutable reference to the value for the given key.
164  pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
165  where
166    K: Borrow<Q>,
167    Q: Hash + Eq + ?Sized,
168  {
169    self.0.get_mut(key)
170  }
171
172  /// Gets the key and value for the given key.
173  pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
174  where
175    K: Borrow<Q>,
176    Q: Hash + Eq + ?Sized,
177  {
178    self.0.get_key_value(key)
179  }
180
181  /// Gets if the map contains the given key.
182  pub fn contains_key<Q>(&self, key: &Q) -> bool
183  where
184    K: Borrow<Q>,
185    Q: Hash + Eq + ?Sized,
186  {
187    self.0.contains_key(key)
188  }
189
190  /// Removes and returns the value for the given key.
191  pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
192  where
193    K: Borrow<Q>,
194    Q: Hash + Eq + ?Sized,
195  {
196    self.0.remove(key)
197  }
198
199  /// Removes and returns the entry for the given key.
200  pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
201  where
202    K: Borrow<Q>,
203    Q: Hash + Eq + ?Sized,
204  {
205    self.0.remove_entry(key)
206  }
207}
208
209#[cfg(feature = "preserve_order")]
210impl<K: Hash + Eq, V> Map<K, V> {
211  /// Gets a reference to the value for the given key.
212  pub fn get<Q>(&self, key: &Q) -> Option<&V>
213  where
214    Q: Hash + indexmap::Equivalent<K> + ?Sized,
215  {
216    self.0.get(key)
217  }
218
219  /// Gets a mutable reference to the value for the given key.
220  pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
221  where
222    Q: Hash + indexmap::Equivalent<K> + ?Sized,
223  {
224    self.0.get_mut(key)
225  }
226
227  /// Gets the key and value for the given key.
228  pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
229  where
230    Q: Hash + indexmap::Equivalent<K> + ?Sized,
231  {
232    self.0.get_key_value(key)
233  }
234
235  /// Gets if the map contains the given key.
236  pub fn contains_key<Q>(&self, key: &Q) -> bool
237  where
238    Q: Hash + indexmap::Equivalent<K> + ?Sized,
239  {
240    self.0.contains_key(key)
241  }
242
243  /// Removes and returns the value for the given key, preserving the order of
244  /// the remaining entries.
245  pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
246  where
247    Q: Hash + indexmap::Equivalent<K> + ?Sized,
248  {
249    self.0.shift_remove(key)
250  }
251
252  /// Removes and returns the entry for the given key, preserving the order of
253  /// the remaining entries.
254  pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
255  where
256    Q: Hash + indexmap::Equivalent<K> + ?Sized,
257  {
258    self.0.shift_remove_entry(key)
259  }
260}
261
262impl<K, V> Default for Map<K, V> {
263  fn default() -> Self {
264    Map::new()
265  }
266}
267
268impl<K: Clone, V: Clone> Clone for Map<K, V> {
269  fn clone(&self) -> Self {
270    Map(self.0.clone())
271  }
272}
273
274impl<K: std::fmt::Debug, V: std::fmt::Debug> std::fmt::Debug for Map<K, V> {
275  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
276    self.0.fmt(f)
277  }
278}
279
280impl<K: Hash + Eq, V: PartialEq> PartialEq for Map<K, V> {
281  fn eq(&self, other: &Self) -> bool {
282    self.0 == other.0
283  }
284}
285
286impl<K: Hash + Eq, V: Eq> Eq for Map<K, V> {}
287
288impl<K: Hash + Eq, V> FromIterator<(K, V)> for Map<K, V> {
289  fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
290    Map(MapInner::from_iter(iter))
291  }
292}
293
294impl<K: Hash + Eq, V> Extend<(K, V)> for Map<K, V> {
295  fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
296    self.0.extend(iter);
297  }
298}
299
300#[cfg(not(feature = "preserve_order"))]
301impl<K: Hash + Eq + Borrow<Q>, Q: Hash + Eq + ?Sized, V> std::ops::Index<&Q> for Map<K, V> {
302  type Output = V;
303  fn index(&self, key: &Q) -> &V {
304    &self.0[key]
305  }
306}
307
308#[cfg(feature = "preserve_order")]
309impl<K: Hash + Eq, Q: Hash + indexmap::Equivalent<K> + ?Sized, V> std::ops::Index<&Q> for Map<K, V> {
310  type Output = V;
311  fn index(&self, key: &Q) -> &V {
312    &self.0[key]
313  }
314}
315
316impl<K, V> IntoIterator for Map<K, V> {
317  type Item = (K, V);
318  type IntoIter = IntoIter<K, V>;
319
320  fn into_iter(self) -> Self::IntoIter {
321    self.0.into_iter()
322  }
323}
324
325impl<'a, K, V> IntoIterator for &'a Map<K, V> {
326  type Item = (&'a K, &'a V);
327  type IntoIter = Iter<'a, K, V>;
328
329  fn into_iter(self) -> Self::IntoIter {
330    self.0.iter()
331  }
332}
333
334impl<'a, K, V> IntoIterator for &'a mut Map<K, V> {
335  type Item = (&'a K, &'a mut V);
336  type IntoIter = IterMut<'a, K, V>;
337
338  fn into_iter(self) -> Self::IntoIter {
339    self.0.iter_mut()
340  }
341}
342
343#[cfg(test)]
344mod test {
345  use super::*;
346
347  #[test]
348  fn drop_in_api() {
349    let mut map: Map<String, i32> = Map::new();
350    assert!(map.is_empty());
351
352    map.insert("a".to_string(), 1);
353    map.insert("b".to_string(), 2);
354    *map.entry("c".to_string()).or_insert(0) += 3;
355    *map.entry("a".to_string()).or_insert(0) += 10;
356    assert_eq!(map.len(), 3);
357
358    // lookups, including the `Index` impl
359    assert_eq!(map.get("a"), Some(&11));
360    assert_eq!(map["b"], 2);
361    assert!(map.contains_key("c"));
362    assert_eq!(map.get("missing"), None);
363
364    // mutation
365    if let Some(v) = map.get_mut("b") {
366      *v = 20;
367    }
368    assert_eq!(map.get("b"), Some(&20));
369
370    // removal
371    assert_eq!(map.remove("c"), Some(3));
372    assert_eq!(map.remove("c"), None);
373    assert_eq!(map.remove_entry("a"), Some(("a".to_string(), 11)));
374
375    // retain
376    map.retain(|_, v| *v > 15);
377    assert_eq!(map.len(), 1);
378    assert!(map.contains_key("b"));
379
380    // iteration by reference
381    let mut count = 0;
382    for (_k, _v) in &map {
383      count += 1;
384    }
385    assert_eq!(count, 1);
386
387    // FromIterator + Extend
388    let mut other: Map<String, i32> = [("x".to_string(), 1)].into_iter().collect();
389    other.extend([("y".to_string(), 2)]);
390    assert_eq!(other.len(), 2);
391  }
392}