blob: a3b33ed67d5febcfde4a22de8839f7493685bd1e [file] [log] [blame]
David Tolnaye352c1e2020-12-31 16:41:05 -08001use std::borrow::Borrow;
2use std::hash::Hash;
3use std::ops::Index;
4
5pub use self::unordered::UnorderedMap;
6pub use std::collections::hash_map::Entry;
7
8mod unordered {
9 use crate::syntax::set::UnorderedSet;
10 use std::borrow::Borrow;
11 use std::collections::hash_map::{Entry, HashMap};
12 use std::hash::Hash;
13
14 // Wrapper prohibits accidentally introducing iteration over the map, which
15 // could lead to nondeterministic generated code.
16 pub struct UnorderedMap<K, V>(HashMap<K, V>);
17
18 impl<K, V> UnorderedMap<K, V> {
19 pub fn new() -> Self {
20 UnorderedMap(HashMap::new())
21 }
22 }
23
24 impl<K, V> UnorderedMap<K, V>
25 where
26 K: Hash + Eq,
27 {
28 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
29 self.0.insert(key, value)
30 }
31
32 pub fn contains_key<Q>(&self, key: &Q) -> bool
33 where
34 K: Borrow<Q>,
35 Q: ?Sized + Hash + Eq,
36 {
37 self.0.contains_key(key)
38 }
39
40 pub fn get<Q>(&self, key: &Q) -> Option<&V>
41 where
42 K: Borrow<Q>,
43 Q: ?Sized + Hash + Eq,
44 {
45 self.0.get(key)
46 }
47
48 pub fn entry(&mut self, key: K) -> Entry<K, V> {
49 self.0.entry(key)
50 }
51
52 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
53 where
54 K: Borrow<Q>,
55 Q: ?Sized + Hash + Eq,
56 {
57 self.0.remove(key)
58 }
59
60 pub fn keys(&self) -> UnorderedSet<K>
61 where
62 K: Copy,
63 {
64 let mut set = UnorderedSet::new();
65 for key in self.0.keys() {
66 set.insert(*key);
67 }
68 set
69 }
70 }
71}
72
73impl<K, V> Default for UnorderedMap<K, V> {
74 fn default() -> Self {
75 UnorderedMap::new()
76 }
77}
78
79impl<Q, K, V> Index<&Q> for UnorderedMap<K, V>
80where
81 K: Borrow<Q> + Hash + Eq,
82 Q: ?Sized + Hash + Eq,
83{
84 type Output = V;
85
86 fn index(&self, key: &Q) -> &V {
87 self.get(key).unwrap()
88 }
89}