phf/
map.rs

1//! An immutable map constructed at compile time.
2use core::fmt;
3use core::iter::FusedIterator;
4use core::iter::IntoIterator;
5use core::ops::Index;
6use core::slice;
7use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
8#[cfg(feature = "serde")]
9use serde::ser::{Serialize, SerializeMap, Serializer};
10
11/// An immutable map constructed at compile time.
12///
13/// ## Note
14///
15/// The fields of this struct are public so that they may be initialized by the
16/// `phf_map!` macro and code generation. They are subject to change at any
17/// time and should never be accessed directly.
18pub struct Map<K: 'static, V: 'static> {
19    #[doc(hidden)]
20    pub key: HashKey,
21    #[doc(hidden)]
22    pub disps: &'static [(u32, u32)],
23    #[doc(hidden)]
24    pub entries: &'static [(K, V)],
25}
26
27impl<K, V> fmt::Debug for Map<K, V>
28where
29    K: fmt::Debug,
30    V: fmt::Debug,
31{
32    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
33        fmt.debug_map().entries(self.entries()).finish()
34    }
35}
36
37impl<'a, K, V, T: ?Sized> Index<&'a T> for Map<K, V>
38where
39    T: Eq + PhfHash,
40    K: PhfBorrow<T>,
41{
42    type Output = V;
43
44    fn index(&self, k: &'a T) -> &V {
45        self.get(k).expect("invalid key")
46    }
47}
48
49impl<K, V> Default for Map<K, V> {
50    fn default() -> Self {
51        Self::new()
52    }
53}
54
55impl<K, V> Map<K, V> {
56    /// Create a new, empty, immutable map.
57    #[inline]
58    pub const fn new() -> Self {
59        Self {
60            key: 0,
61            disps: &[],
62            entries: &[],
63        }
64    }
65
66    /// Returns the number of entries in the `Map`.
67    #[inline]
68    pub const fn len(&self) -> usize {
69        self.entries.len()
70    }
71
72    /// Returns true if the `Map` is empty.
73    #[inline]
74    pub const fn is_empty(&self) -> bool {
75        self.len() == 0
76    }
77
78    /// Determines if `key` is in the `Map`.
79    pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
80    where
81        T: Eq + PhfHash,
82        K: PhfBorrow<T>,
83    {
84        self.get(key).is_some()
85    }
86
87    /// Returns a reference to the value that `key` maps to.
88    pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
89    where
90        T: Eq + PhfHash,
91        K: PhfBorrow<T>,
92    {
93        self.get_entry(key).map(|e| e.1)
94    }
95
96    /// Returns a reference to the map's internal static instance of the given
97    /// key.
98    ///
99    /// This can be useful for interning schemes.
100    pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
101    where
102        T: Eq + PhfHash,
103        K: PhfBorrow<T>,
104    {
105        self.get_entry(key).map(|e| e.0)
106    }
107
108    /// Like `get`, but returns both the key and the value.
109    pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
110    where
111        T: Eq + PhfHash,
112        K: PhfBorrow<T>,
113    {
114        if self.disps.is_empty() {
115            return None;
116        } //Prevent panic on empty map
117        let hashes = phf_shared::hash(key, &self.key);
118        let index = phf_shared::get_index(&hashes, self.disps, self.entries.len());
119        let entry = &self.entries[index as usize];
120        let b: &T = entry.0.borrow();
121        if b == key {
122            Some((&entry.0, &entry.1))
123        } else {
124            None
125        }
126    }
127
128    /// Returns an iterator over the key/value pairs in the map.
129    ///
130    /// Entries are returned in an arbitrary but fixed order.
131    pub fn entries(&self) -> Entries<'_, K, V> {
132        Entries {
133            iter: self.entries.iter(),
134        }
135    }
136
137    /// Returns an iterator over the keys in the map.
138    ///
139    /// Keys are returned in an arbitrary but fixed order.
140    pub fn keys(&self) -> Keys<'_, K, V> {
141        Keys {
142            iter: self.entries(),
143        }
144    }
145
146    /// Returns an iterator over the values in the map.
147    ///
148    /// Values are returned in an arbitrary but fixed order.
149    pub fn values(&self) -> Values<'_, K, V> {
150        Values {
151            iter: self.entries(),
152        }
153    }
154}
155
156impl<'a, K, V> IntoIterator for &'a Map<K, V> {
157    type Item = (&'a K, &'a V);
158    type IntoIter = Entries<'a, K, V>;
159
160    fn into_iter(self) -> Entries<'a, K, V> {
161        self.entries()
162    }
163}
164
165/// An iterator over the key/value pairs in a `Map`.
166pub struct Entries<'a, K, V> {
167    iter: slice::Iter<'a, (K, V)>,
168}
169
170impl<'a, K, V> Clone for Entries<'a, K, V> {
171    #[inline]
172    fn clone(&self) -> Self {
173        Self {
174            iter: self.iter.clone(),
175        }
176    }
177}
178
179impl<'a, K, V> fmt::Debug for Entries<'a, K, V>
180where
181    K: fmt::Debug,
182    V: fmt::Debug,
183{
184    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
185        f.debug_list().entries(self.clone()).finish()
186    }
187}
188
189impl<'a, K, V> Iterator for Entries<'a, K, V> {
190    type Item = (&'a K, &'a V);
191
192    fn next(&mut self) -> Option<(&'a K, &'a V)> {
193        self.iter.next().map(|&(ref k, ref v)| (k, v))
194    }
195
196    fn size_hint(&self) -> (usize, Option<usize>) {
197        self.iter.size_hint()
198    }
199}
200
201impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
202    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
203        self.iter.next_back().map(|e| (&e.0, &e.1))
204    }
205}
206
207impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}
208
209impl<'a, K, V> FusedIterator for Entries<'a, K, V> {}
210
211/// An iterator over the keys in a `Map`.
212pub struct Keys<'a, K, V> {
213    iter: Entries<'a, K, V>,
214}
215
216impl<'a, K, V> Clone for Keys<'a, K, V> {
217    #[inline]
218    fn clone(&self) -> Self {
219        Self {
220            iter: self.iter.clone(),
221        }
222    }
223}
224
225impl<'a, K, V> fmt::Debug for Keys<'a, K, V>
226where
227    K: fmt::Debug,
228{
229    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230        f.debug_list().entries(self.clone()).finish()
231    }
232}
233
234impl<'a, K, V> Iterator for Keys<'a, K, V> {
235    type Item = &'a K;
236
237    fn next(&mut self) -> Option<&'a K> {
238        self.iter.next().map(|e| e.0)
239    }
240
241    fn size_hint(&self) -> (usize, Option<usize>) {
242        self.iter.size_hint()
243    }
244}
245
246impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
247    fn next_back(&mut self) -> Option<&'a K> {
248        self.iter.next_back().map(|e| e.0)
249    }
250}
251
252impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
253
254impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
255
256/// An iterator over the values in a `Map`.
257pub struct Values<'a, K, V> {
258    iter: Entries<'a, K, V>,
259}
260
261impl<'a, K, V> Clone for Values<'a, K, V> {
262    #[inline]
263    fn clone(&self) -> Self {
264        Self {
265            iter: self.iter.clone(),
266        }
267    }
268}
269
270impl<'a, K, V> fmt::Debug for Values<'a, K, V>
271where
272    V: fmt::Debug,
273{
274    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
275        f.debug_list().entries(self.clone()).finish()
276    }
277}
278
279impl<'a, K, V> Iterator for Values<'a, K, V> {
280    type Item = &'a V;
281
282    fn next(&mut self) -> Option<&'a V> {
283        self.iter.next().map(|e| e.1)
284    }
285
286    fn size_hint(&self) -> (usize, Option<usize>) {
287        self.iter.size_hint()
288    }
289}
290
291impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
292    fn next_back(&mut self) -> Option<&'a V> {
293        self.iter.next_back().map(|e| e.1)
294    }
295}
296
297impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
298
299impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
300
301#[cfg(feature = "serde")]
302impl<K, V> Serialize for Map<K, V>
303where
304    K: Serialize,
305    V: Serialize,
306{
307    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
308    where
309        S: Serializer,
310    {
311        let mut map = serializer.serialize_map(Some(self.len()))?;
312        for (k, v) in self.entries() {
313            map.serialize_entry(k, v)?;
314        }
315        map.end()
316    }
317}