1use 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#[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#[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 #[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 #[inline]
123 pub const fn len(&self) -> usize {
124 self.entries.len()
125 }
126
127 #[inline]
129 pub const fn is_empty(&self) -> bool {
130 self.len() == 0
131 }
132
133 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 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 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 #[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 } 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 #[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 pub fn entries(&self) -> Entries<'_, K, V> {
214 Entries {
215 iter: self.entries.iter(),
216 }
217 }
218
219 pub fn keys(&self) -> Keys<'_, K, V> {
223 Keys {
224 iter: self.entries(),
225 }
226 }
227
228 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
247pub 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
293pub 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
338pub 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}