phf/
ordered_map.rs

1//! An order-preserving immutable map constructed at compile time.
2use core::borrow::Borrow;
3use core::iter::IntoIterator;
4use core::ops::Index;
5use core::fmt;
6use core::slice;
7use phf_shared::{self, PhfHash};
8
9use Slice;
10
11/// An order-preserving immutable map constructed at compile time.
12///
13/// Unlike a `Map`, iteration order is guaranteed to match the definition
14/// order.
15///
16/// ## Note
17///
18/// The fields of this struct are public so that they may be initialized by the
19/// `phf_ordered_map!` macro and code generation. They are subject to change at
20/// any time and should never be accessed directly.
21pub struct OrderedMap<K: 'static, V: 'static> {
22    #[doc(hidden)]
23    pub key: u64,
24    #[doc(hidden)]
25    pub disps: Slice<(u32, u32)>,
26    #[doc(hidden)]
27    pub idxs: Slice<usize>,
28    #[doc(hidden)]
29    pub entries: Slice<(K, V)>,
30}
31
32impl<K, V> fmt::Debug for OrderedMap<K, V> where K: fmt::Debug, V: fmt::Debug {
33    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
34        fmt.debug_map().entries(self.entries()).finish()
35    }
36}
37
38impl<'a, K, V, T: ?Sized> Index<&'a T> for OrderedMap<K, V> where T: Eq + PhfHash, K: Borrow<T> {
39    type Output = V;
40
41    fn index(&self, k: &'a T) -> &V {
42        self.get(k).expect("invalid key")
43    }
44}
45
46impl<K, V> OrderedMap<K, V> {
47    /// Returns the number of entries in the `Map`.
48    pub fn len(&self) -> usize {
49        self.entries.len()
50    }
51
52    /// Returns true if the `Map` is empty.
53    pub fn is_empty(&self) -> bool {
54        self.len() == 0
55    }
56
57    /// Returns a reference to the value that `key` maps to.
58    pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
59        where T: Eq + PhfHash,
60              K: Borrow<T>
61    {
62        self.get_entry(key).map(|e| e.1)
63    }
64
65    /// Returns a reference to the map's internal static instance of the given
66    /// key.
67    ///
68    /// This can be useful for interning schemes.
69    pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
70        where T: Eq + PhfHash,
71              K: Borrow<T>
72    {
73        self.get_entry(key).map(|e| e.0)
74    }
75
76    /// Determines if `key` is in the `Map`.
77    pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
78        where T: Eq + PhfHash,
79              K: Borrow<T>
80    {
81        self.get(key).is_some()
82    }
83
84    /// Returns the index of the key within the list used to initialize
85    /// the ordered map.
86    pub fn get_index<T: ?Sized>(&self, key: &T) -> Option<usize>
87        where T: Eq + PhfHash,
88              K: Borrow<T>
89    {
90        self.get_internal(key).map(|(i, _)| i)
91    }
92
93    /// Returns references to both the key and values at an index
94    /// within the list used to initialize the ordered map. See `.get_index(key)`.
95    pub fn index(&self, index: usize) -> Option<(&K, &V)> {
96        self.entries.get(index).map(|&(ref k, ref v)| (k, v))
97    }
98
99    /// Like `get`, but returns both the key and the value.
100    pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
101        where T: Eq + PhfHash,
102              K: Borrow<T>
103    {
104        self.get_internal(key).map(|(_, e)| e)
105    }
106
107    fn get_internal<T: ?Sized>(&self, key: &T) -> Option<(usize, (&K, &V))>
108        where T: Eq + PhfHash,
109              K: Borrow<T>
110    {
111        let hash = phf_shared::hash(key, self.key);
112        let idx_index = phf_shared::get_index(hash, &*self.disps, self.idxs.len());
113        let idx = self.idxs[idx_index as usize];
114        let entry = &self.entries[idx];
115
116        let b: &T = entry.0.borrow();
117        if b == key {
118            Some((idx, (&entry.0, &entry.1)))
119        } else {
120            None
121        }
122    }
123
124    /// Returns an iterator over the key/value pairs in the map.
125    ///
126    /// Entries are returned in the same order in which they were defined.
127    pub fn entries<'a>(&'a self) -> Entries<'a, K, V> {
128        Entries { iter: self.entries.iter() }
129    }
130
131    /// Returns an iterator over the keys in the map.
132    ///
133    /// Keys are returned in the same order in which they were defined.
134    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
135        Keys { iter: self.entries() }
136    }
137
138    /// Returns an iterator over the values in the map.
139    ///
140    /// Values are returned in the same order in which they were defined.
141    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
142        Values { iter: self.entries() }
143    }
144}
145
146impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
147    type Item = (&'a K, &'a V);
148    type IntoIter = Entries<'a, K, V>;
149
150    fn into_iter(self) -> Entries<'a, K, V> {
151        self.entries()
152    }
153}
154
155/// An iterator over the entries in a `OrderedMap`.
156pub struct Entries<'a, K: 'a, V: 'a> {
157    iter: slice::Iter<'a, (K, V)>,
158}
159
160impl<'a, K, V> Iterator for Entries<'a, K, V> {
161    type Item = (&'a K, &'a V);
162
163    fn next(&mut self) -> Option<(&'a K, &'a V)> {
164        self.iter.next().map(|e| (&e.0, &e.1))
165    }
166
167    fn size_hint(&self) -> (usize, Option<usize>) {
168        self.iter.size_hint()
169    }
170}
171
172impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
173    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
174        self.iter.next_back().map(|e| (&e.0, &e.1))
175    }
176}
177
178impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}
179
180/// An iterator over the keys in a `OrderedMap`.
181pub struct Keys<'a, K: 'a, V: 'a> {
182    iter: Entries<'a, K, V>,
183}
184
185impl<'a, K, V> Iterator for Keys<'a, K, V> {
186    type Item = &'a K;
187
188    fn next(&mut self) -> Option<&'a K> {
189        self.iter.next().map(|e| e.0)
190    }
191
192    fn size_hint(&self) -> (usize, Option<usize>) {
193        self.iter.size_hint()
194    }
195}
196
197impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
198    fn next_back(&mut self) -> Option<&'a K> {
199        self.iter.next_back().map(|e| e.0)
200    }
201}
202
203impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
204
205/// An iterator over the values in a `OrderedMap`.
206pub struct Values<'a, K: 'a, V: 'a> {
207    iter: Entries<'a, K, V>,
208}
209
210impl<'a, K, V> Iterator for Values<'a, K, V> {
211    type Item = &'a V;
212
213    fn next(&mut self) -> Option<&'a V> {
214        self.iter.next().map(|e| e.1)
215    }
216
217    fn size_hint(&self) -> (usize, Option<usize>) {
218        self.iter.size_hint()
219    }
220}
221
222impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
223    fn next_back(&mut self) -> Option<&'a V> {
224        self.iter.next_back().map(|e| e.1)
225    }
226}
227
228impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}