Skip to main content

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