turbo_frozenmap/
map.rs

1use std::{
2    borrow::Borrow,
3    collections::{BTreeMap, HashMap},
4    fmt::{self, Debug},
5    hash::BuildHasher,
6    iter::FusedIterator,
7    ops::{Bound, Index, RangeBounds},
8};
9
10use bincode::{BorrowDecode, Decode, Encode};
11use indexmap::IndexMap;
12use serde::{Deserialize, Serialize};
13
14/// A compact frozen (immutable) ordered map backed by a sorted boxed slice.
15///
16/// This is a read-only map that stores key-value pairs in a contiguous, sorted array. It provides
17/// efficient sorted iteration and binary search lookups, but cannot be modified after construction.
18///
19/// # Construction
20///
21/// If you're building a new map, and you don't expect many overlapping keys, consider pushing
22/// entries into a [`Vec<(K, V)>`] and calling [`FrozenMap::from`]. It is typically cheaper to
23/// collect into a [`Vec`] and sort the entries once at the end than it is to maintain a temporary
24/// map data structure.
25///
26/// If you already have a map, need to perform lookups during construction, or you have many
27/// overlapping keys that you don't want to temporarily hold onto, you can use the provided [`From`]
28/// trait implementations to create a [`FrozenMap`] from one of many common collections. You should
29/// prefer using a [`BTreeMap`], as it matches the sorted iteration order of [`FrozenMap`] and
30/// avoids a sort operation during conversion.
31///
32/// If you don't have an existing collection, you can use the [`FromIterator<(K, V)>`] trait
33/// implementation to [`.collect()`][Iterator::collect] tuples into a [`FrozenMap`].
34///
35/// Finally, if you have a list of pre-sorted tuples with unique keys, you can use the advanced
36/// [`FrozenMap::from_unique_sorted_box`] or [`FrozenMap::from_unique_sorted_box_unchecked`]
37/// constructors, which provide the cheapest possible construction.
38///
39/// Overlapping keys encountered during construction preserve the last overlapping entry, matching
40/// similar behavior for other maps in the standard library.
41#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode, Serialize, Deserialize)]
42#[rustfmt::skip] // rustfmt breaks bincode's proc macro string processing
43#[bincode(
44    decode_bounds = "K: Decode<__Context> + 'static, V: Decode<__Context> + 'static",
45    borrow_decode_bounds = "K: BorrowDecode<'__de, __Context> + '__de, V: BorrowDecode<'__de, __Context> + '__de"
46)]
47pub struct FrozenMap<K, V> {
48    /// Invariant: entries are sorted by key in ascending order with no overlapping keys.
49    pub(crate) entries: Box<[(K, V)]>,
50}
51
52impl<K, V> FrozenMap<K, V> {
53    /// Creates an empty [`FrozenMap`]. Does not perform any heap allocations.
54    pub fn new() -> Self {
55        FrozenMap {
56            // Box does not perform heap allocations for zero-sized types.
57            // In theory this could even be `const` using `Unique::dangling`, but there's no way to
58            // construct a `Box` from a pointer during `const`.
59            entries: Box::from([]),
60        }
61    }
62}
63
64impl<K, V> FrozenMap<K, V>
65where
66    K: Ord,
67{
68    /// Creates a [`FrozenMap`] from a pre-sorted boxed slice with unique keys.
69    ///
70    /// Panics if the keys in `entries` are not unique and sorted.
71    pub fn from_unique_sorted_box(entries: Box<[(K, V)]>) -> Self {
72        assert_unique_sorted(&entries);
73        FrozenMap { entries }
74    }
75
76    /// Creates a [`FrozenMap`] from a pre-sorted boxed slice with unique keys.
77    ///
78    /// # Correctness
79    ///
80    /// The caller must ensure that:
81    /// - The entries are sorted by key in ascending order according to [`K: Ord`][Ord]
82    /// - There are no overlapping keys
83    ///
84    /// If these invariants are not upheld, the map will behave incorrectly (e.g.,
85    /// [`FrozenMap::get`] may fail to find keys that are present), but no memory unsafety will
86    /// occur.
87    ///
88    /// When `debug_assertions` is enabled, this will panic if an invariant is not upheld.
89    pub fn from_unique_sorted_box_unchecked(entries: Box<[(K, V)]>) -> Self {
90        debug_assert_unique_sorted(&entries);
91        FrozenMap { entries }
92    }
93
94    /// Helper: Sorts keys before constructing. Does not perform any assertions.
95    ///
96    /// The caller of this helper should provide a fast-path for empty collections.
97    pub(crate) fn from_unique_box_inner(mut entries: Box<[(K, V)]>) -> Self {
98        entries.sort_unstable_by(|a, b| a.0.cmp(&b.0));
99        Self::from_unique_sorted_box_unchecked(entries)
100    }
101
102    /// Helper: Sorts and deduplicates keys before constructing. Does not perform any assertions.
103    ///
104    /// The caller of this helper should provide a fast-path for empty collections.
105    pub(crate) fn from_vec_inner(mut entries: Vec<(K, V)>) -> Self {
106        // stable sort preserves insertion order for overlapping keys
107        entries.sort_by(|a, b| a.0.cmp(&b.0));
108        // Deduplicate, keeping the last value for each key.
109        // `dedup_by` removes the first argument when returning true, so we swap to keep the later
110        // (last) value in the earlier slot.
111        entries.dedup_by(|later, earlier| {
112            if later.0 == earlier.0 {
113                std::mem::swap(later, earlier);
114                true
115            } else {
116                false
117            }
118        });
119        Self::from_unique_sorted_box_unchecked(entries.into_boxed_slice())
120    }
121}
122
123#[track_caller]
124fn assert_unique_sorted<K: Ord, V>(entries: &[(K, V)]) {
125    assert!(
126        entries.is_sorted_by(|a, b| a.0 < b.0),
127        "FrozenMap entries must be unique and sorted",
128    )
129}
130
131#[track_caller]
132fn debug_assert_unique_sorted<K: Ord, V>(entries: &[(K, V)]) {
133    debug_assert!(
134        entries.is_sorted_by(|a, b| a.0 < b.0),
135        "FrozenMap entries must be unique and sorted",
136    )
137}
138
139impl<K: Ord, V> FromIterator<(K, V)> for FrozenMap<K, V> {
140    /// Creates a [`FrozenMap`] from an iterator of key-value pairs.
141    ///
142    /// If there are overlapping keys, the last entry for each key is kept.
143    fn from_iter<T: IntoIterator<Item = (K, V)>>(entries: T) -> Self {
144        let entries: Vec<_> = entries.into_iter().collect();
145        Self::from(entries)
146    }
147}
148
149impl<K, V> From<BTreeMap<K, V>> for FrozenMap<K, V> {
150    /// Creates a [`FrozenMap`] from a [`BTreeMap`].
151    ///
152    /// This is more efficient than `From<HashMap<K, V>>` because [`BTreeMap`] already iterates in
153    /// sorted order, so no re-sorting is needed.
154    fn from(map: BTreeMap<K, V>) -> Self {
155        if map.is_empty() {
156            return Self::new();
157        }
158        FrozenMap {
159            entries: map.into_iter().collect(),
160        }
161    }
162}
163
164impl<K, V, S> From<HashMap<K, V, S>> for FrozenMap<K, V>
165where
166    K: Ord,
167    S: BuildHasher,
168{
169    /// Creates a [`FrozenMap`] from a [`HashMap`].
170    ///
171    /// The entries are sorted by key during construction.
172    fn from(map: HashMap<K, V, S>) -> Self {
173        if map.is_empty() {
174            return Self::new();
175        }
176        Self::from_unique_box_inner(map.into_iter().collect())
177    }
178}
179
180impl<K, V, S> From<IndexMap<K, V, S>> for FrozenMap<K, V>
181where
182    K: Ord,
183    S: BuildHasher,
184{
185    /// Creates a [`FrozenMap`] from an [`IndexMap`].
186    ///
187    /// The entries are sorted by key during construction.
188    fn from(map: IndexMap<K, V, S>) -> Self {
189        if map.is_empty() {
190            return Self::new();
191        }
192        Self::from_unique_box_inner(map.into_iter().collect())
193    }
194}
195
196impl<K: Ord, V> From<Vec<(K, V)>> for FrozenMap<K, V> {
197    /// Creates a [`FrozenMap`] from a [`Vec`] of key-value pairs.
198    ///
199    /// If there are overlapping keys, the last entry for each key is kept.
200    fn from(entries: Vec<(K, V)>) -> Self {
201        if entries.is_empty() {
202            return Self::new();
203        }
204        Self::from_vec_inner(entries)
205    }
206}
207
208impl<K: Ord, V> From<Box<[(K, V)]>> for FrozenMap<K, V> {
209    /// Creates a [`FrozenMap`] from a boxed slice of key-value pairs.
210    ///
211    /// If there are overlapping keys, the last entry for each key is kept.
212    fn from(entries: Box<[(K, V)]>) -> Self {
213        if entries.is_empty() {
214            return Self::new();
215        }
216        Self::from_vec_inner(Vec::from(entries))
217    }
218}
219
220impl<K, V> From<&[(K, V)]> for FrozenMap<K, V>
221where
222    K: Ord + Clone,
223    V: Clone,
224{
225    /// Creates a [`FrozenMap`] from a slice of key-value pairs. Keys and values are cloned.
226    ///
227    /// If there are overlapping keys, the last entry for each key is kept.
228    fn from(entries: &[(K, V)]) -> Self {
229        if entries.is_empty() {
230            return Self::new();
231        }
232        Self::from_vec_inner(Vec::from(entries))
233    }
234}
235
236impl<K: Ord, V, const N: usize> From<[(K, V); N]> for FrozenMap<K, V> {
237    /// Creates a [`FrozenMap`] from an owned array of key-value pairs.
238    ///
239    /// If there are overlapping keys, the last entry for each key is kept.
240    fn from(entries: [(K, V); N]) -> Self {
241        if entries.is_empty() {
242            return Self::new();
243        }
244        Self::from_vec_inner(Vec::from(entries))
245    }
246}
247
248impl<K, V> FrozenMap<K, V> {
249    /// Returns the number of elements in the map.
250    pub const fn len(&self) -> usize {
251        self.entries.len()
252    }
253
254    /// Returns `true` if the map contains no elements.
255    pub const fn is_empty(&self) -> bool {
256        self.entries.is_empty()
257    }
258
259    /// Returns a reference to the underlying sorted slice.
260    pub const fn as_slice(&self) -> &[(K, V)] {
261        &self.entries
262    }
263
264    /// Returns a reference to the value corresponding to the key.
265    pub fn get<Q>(&self, key: &Q) -> Option<&V>
266    where
267        K: Borrow<Q> + Ord,
268        Q: Ord + ?Sized,
269    {
270        self.get_key_value(key).map(|(_, v)| v)
271    }
272
273    /// Returns the key-value pair corresponding to the supplied key.
274    pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
275    where
276        K: Borrow<Q> + Ord,
277        Q: Ord + ?Sized,
278    {
279        let idx = self
280            .entries
281            .binary_search_by(|(k, _)| k.borrow().cmp(key))
282            .ok()?;
283        let (k, v) = &self.entries[idx];
284        Some((k, v))
285    }
286
287    /// Returns `true` if the map contains a value for the specified key.
288    pub fn contains_key<Q>(&self, key: &Q) -> bool
289    where
290        K: Borrow<Q> + Ord,
291        Q: Ord + ?Sized,
292    {
293        self.entries
294            .binary_search_by(|(k, _)| k.borrow().cmp(key))
295            .is_ok()
296    }
297
298    /// Returns the first key-value pair in the map.
299    pub fn first_key_value(&self) -> Option<(&K, &V)> {
300        self.entries.first().map(|(k, v)| (k, v))
301    }
302
303    /// Returns the last key-value pair in the map.
304    pub fn last_key_value(&self) -> Option<(&K, &V)> {
305        self.entries.last().map(|(k, v)| (k, v))
306    }
307
308    /// Gets an iterator over the entries of the map, sorted by key.
309    pub fn iter(&self) -> Iter<'_, K, V> {
310        Iter {
311            inner: self.entries.iter(),
312        }
313    }
314
315    /// Gets an iterator over the keys of the map, in sorted order.
316    pub fn keys(&self) -> Keys<'_, K, V> {
317        Keys { inner: self.iter() }
318    }
319
320    /// Gets an iterator over the values of the map, in order by key.
321    pub fn values(&self) -> Values<'_, K, V> {
322        Values { inner: self.iter() }
323    }
324
325    /// Creates a consuming iterator visiting all the keys, in sorted order.
326    pub fn into_keys(self) -> IntoKeys<K, V> {
327        IntoKeys {
328            inner: self.into_iter(),
329        }
330    }
331
332    /// Creates a consuming iterator visiting all the values, in order by key.
333    pub fn into_values(self) -> IntoValues<K, V> {
334        IntoValues {
335            inner: self.into_iter(),
336        }
337    }
338
339    /// Constructs a double-ended iterator over a sub-range of entries in the map.
340    pub fn range<T, R>(&self, range: R) -> Range<'_, K, V>
341    where
342        T: Ord + ?Sized,
343        K: Borrow<T> + Ord,
344        R: RangeBounds<T>,
345    {
346        let start = match range.start_bound() {
347            Bound::Included(key) => self
348                .entries
349                .binary_search_by(|(k, _)| k.borrow().cmp(key))
350                .unwrap_or_else(|i| i),
351            Bound::Excluded(key) => {
352                match self.entries.binary_search_by(|(k, _)| k.borrow().cmp(key)) {
353                    Ok(i) => i + 1,
354                    Err(i) => i,
355                }
356            }
357            Bound::Unbounded => 0,
358        };
359
360        let end = match range.end_bound() {
361            Bound::Included(key) => {
362                match self.entries.binary_search_by(|(k, _)| k.borrow().cmp(key)) {
363                    Ok(i) => i + 1,
364                    Err(i) => i,
365                }
366            }
367            Bound::Excluded(key) => self
368                .entries
369                .binary_search_by(|(k, _)| k.borrow().cmp(key))
370                .unwrap_or_else(|i| i),
371            Bound::Unbounded => self.entries.len(),
372        };
373
374        let slice = if start <= end && end <= self.entries.len() {
375            &self.entries[start..end]
376        } else {
377            &[]
378        };
379
380        Range {
381            inner: slice.iter(),
382        }
383    }
384
385    /// Extend this [`FrozenMap`] by constructing a new map with the additional entries. New entries
386    /// with overlapping keys will overwrite existing ones.
387    #[must_use]
388    pub fn extend(&self, entries: impl IntoIterator<Item = (K, V)>) -> Self
389    where
390        K: Clone + Ord,
391        V: Clone,
392    {
393        self.as_slice().iter().cloned().chain(entries).collect()
394    }
395}
396
397// Manual implementation because the derive would add unnecessary `K: Default, V: Default` bounds.
398impl<K, V> Default for FrozenMap<K, V> {
399    fn default() -> Self {
400        Self::new()
401    }
402}
403
404impl<K: Debug, V: Debug> Debug for FrozenMap<K, V> {
405    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406        f.debug_map().entries(self.iter()).finish()
407    }
408}
409
410impl<K, Q: ?Sized, V> Index<&Q> for FrozenMap<K, V>
411where
412    K: Borrow<Q> + Ord,
413    Q: Ord,
414{
415    type Output = V;
416
417    fn index(&self, key: &Q) -> &V {
418        self.get(key).expect("no entry found for key")
419    }
420}
421
422impl<K, V> AsRef<[(K, V)]> for FrozenMap<K, V> {
423    fn as_ref(&self) -> &[(K, V)] {
424        self.as_slice()
425    }
426}
427
428impl<K, V> From<FrozenMap<K, V>> for Box<[(K, V)]> {
429    fn from(map: FrozenMap<K, V>) -> Self {
430        map.entries
431    }
432}
433
434impl<'a, K, V> IntoIterator for &'a FrozenMap<K, V> {
435    type Item = (&'a K, &'a V);
436    type IntoIter = Iter<'a, K, V>;
437
438    fn into_iter(self) -> Iter<'a, K, V> {
439        self.iter()
440    }
441}
442
443impl<K, V> IntoIterator for FrozenMap<K, V> {
444    type Item = (K, V);
445    type IntoIter = IntoIter<K, V>;
446
447    fn into_iter(self) -> IntoIter<K, V> {
448        IntoIter {
449            inner: self.entries.into_vec().into_iter(),
450        }
451    }
452}
453
454/// An iterator over the entries of a [`FrozenMap`].
455pub struct Iter<'a, K, V> {
456    inner: std::slice::Iter<'a, (K, V)>,
457}
458
459impl<K: Debug, V: Debug> Debug for Iter<'_, K, V> {
460    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
461        f.debug_list()
462            .entries(self.inner.clone().map(|(k, v)| (k, v)))
463            .finish()
464    }
465}
466
467impl<'a, K, V> Iterator for Iter<'a, K, V> {
468    type Item = (&'a K, &'a V);
469
470    fn next(&mut self) -> Option<Self::Item> {
471        self.inner.next().map(|(k, v)| (k, v))
472    }
473
474    fn size_hint(&self) -> (usize, Option<usize>) {
475        self.inner.size_hint()
476    }
477
478    fn last(mut self) -> Option<Self::Item> {
479        self.next_back()
480    }
481
482    fn nth(&mut self, n: usize) -> Option<Self::Item> {
483        self.inner.nth(n).map(|(k, v)| (k, v))
484    }
485
486    fn count(self) -> usize {
487        self.inner.len()
488    }
489}
490
491impl<K, V> DoubleEndedIterator for Iter<'_, K, V> {
492    fn next_back(&mut self) -> Option<Self::Item> {
493        self.inner.next_back().map(|(k, v)| (k, v))
494    }
495
496    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
497        self.inner.nth_back(n).map(|(k, v)| (k, v))
498    }
499}
500
501impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
502    fn len(&self) -> usize {
503        self.inner.len()
504    }
505}
506
507impl<K, V> FusedIterator for Iter<'_, K, V> {}
508
509// Manual implementation because the derive would add unnecessary `K: Clone, V: Clone` type bounds.
510impl<K, V> Clone for Iter<'_, K, V> {
511    fn clone(&self) -> Self {
512        Self {
513            inner: self.inner.clone(),
514        }
515    }
516}
517
518/// An owning iterator over the entries of a [`FrozenMap`].
519pub struct IntoIter<K, V> {
520    inner: std::vec::IntoIter<(K, V)>,
521}
522
523impl<K: Debug, V: Debug> Debug for IntoIter<K, V> {
524    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525        f.debug_list().entries(self.inner.as_slice()).finish()
526    }
527}
528
529impl<K, V> Iterator for IntoIter<K, V> {
530    type Item = (K, V);
531
532    fn next(&mut self) -> Option<Self::Item> {
533        self.inner.next()
534    }
535
536    fn size_hint(&self) -> (usize, Option<usize>) {
537        self.inner.size_hint()
538    }
539
540    fn count(self) -> usize {
541        self.inner.len()
542    }
543}
544
545impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
546    fn next_back(&mut self) -> Option<Self::Item> {
547        self.inner.next_back()
548    }
549}
550
551impl<K, V> ExactSizeIterator for IntoIter<K, V> {
552    fn len(&self) -> usize {
553        self.inner.len()
554    }
555}
556
557impl<K, V> FusedIterator for IntoIter<K, V> {}
558
559/// An iterator over the keys of a [`FrozenMap`].
560pub struct Keys<'a, K, V> {
561    inner: Iter<'a, K, V>,
562}
563
564impl<K: Debug, V> Debug for Keys<'_, K, V> {
565    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
566        f.debug_list()
567            .entries(self.inner.inner.clone().map(|(k, _)| k))
568            .finish()
569    }
570}
571
572impl<'a, K, V> Iterator for Keys<'a, K, V> {
573    type Item = &'a K;
574
575    fn next(&mut self) -> Option<Self::Item> {
576        self.inner.next().map(|(k, _)| k)
577    }
578
579    fn size_hint(&self) -> (usize, Option<usize>) {
580        self.inner.size_hint()
581    }
582
583    fn last(mut self) -> Option<Self::Item> {
584        self.next_back()
585    }
586
587    fn count(self) -> usize {
588        self.inner.len()
589    }
590}
591
592impl<K, V> DoubleEndedIterator for Keys<'_, K, V> {
593    fn next_back(&mut self) -> Option<Self::Item> {
594        self.inner.next_back().map(|(k, _)| k)
595    }
596}
597
598impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
599    fn len(&self) -> usize {
600        self.inner.len()
601    }
602}
603
604impl<K, V> FusedIterator for Keys<'_, K, V> {}
605
606// Manual implementation because the derive would add unnecessary `K: Clone, V: Clone` type bounds.
607impl<K, V> Clone for Keys<'_, K, V> {
608    fn clone(&self) -> Self {
609        Self {
610            inner: self.inner.clone(),
611        }
612    }
613}
614
615/// An iterator over the values of a [`FrozenMap`].
616pub struct Values<'a, K, V> {
617    inner: Iter<'a, K, V>,
618}
619
620impl<K, V: Debug> Debug for Values<'_, K, V> {
621    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622        f.debug_list()
623            .entries(self.inner.inner.clone().map(|(_, v)| v))
624            .finish()
625    }
626}
627
628impl<'a, K, V> Iterator for Values<'a, K, V> {
629    type Item = &'a V;
630
631    fn next(&mut self) -> Option<Self::Item> {
632        self.inner.next().map(|(_, v)| v)
633    }
634
635    fn size_hint(&self) -> (usize, Option<usize>) {
636        self.inner.size_hint()
637    }
638
639    fn last(mut self) -> Option<Self::Item> {
640        self.next_back()
641    }
642
643    fn count(self) -> usize {
644        self.inner.len()
645    }
646}
647
648impl<K, V> DoubleEndedIterator for Values<'_, K, V> {
649    fn next_back(&mut self) -> Option<Self::Item> {
650        self.inner.next_back().map(|(_, v)| v)
651    }
652}
653
654impl<K, V> ExactSizeIterator for Values<'_, K, V> {
655    fn len(&self) -> usize {
656        self.inner.len()
657    }
658}
659
660impl<K, V> FusedIterator for Values<'_, K, V> {}
661
662// Manual implementation because the derive would add unnecessary `K: Clone, V: Clone` type bounds.
663impl<K, V> Clone for Values<'_, K, V> {
664    fn clone(&self) -> Self {
665        Self {
666            inner: self.inner.clone(),
667        }
668    }
669}
670
671/// An owning iterator over the keys of a [`FrozenMap`].
672pub struct IntoKeys<K, V> {
673    inner: IntoIter<K, V>,
674}
675
676impl<K: Debug, V> Debug for IntoKeys<K, V> {
677    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
678        f.debug_list()
679            .entries(self.inner.inner.as_slice().iter().map(|(k, _)| k))
680            .finish()
681    }
682}
683
684impl<K, V> Iterator for IntoKeys<K, V> {
685    type Item = K;
686
687    fn next(&mut self) -> Option<Self::Item> {
688        self.inner.next().map(|(k, _)| k)
689    }
690
691    fn size_hint(&self) -> (usize, Option<usize>) {
692        self.inner.size_hint()
693    }
694
695    fn count(self) -> usize {
696        self.inner.len()
697    }
698}
699
700impl<K, V> DoubleEndedIterator for IntoKeys<K, V> {
701    fn next_back(&mut self) -> Option<Self::Item> {
702        self.inner.next_back().map(|(k, _)| k)
703    }
704}
705
706impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
707    fn len(&self) -> usize {
708        self.inner.len()
709    }
710}
711
712impl<K, V> FusedIterator for IntoKeys<K, V> {}
713
714/// An owning iterator over the values of a [`FrozenMap`].
715pub struct IntoValues<K, V> {
716    inner: IntoIter<K, V>,
717}
718
719impl<K, V: Debug> Debug for IntoValues<K, V> {
720    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
721        f.debug_list()
722            .entries(self.inner.inner.as_slice().iter().map(|(_, v)| v))
723            .finish()
724    }
725}
726
727impl<K, V> Iterator for IntoValues<K, V> {
728    type Item = V;
729
730    fn next(&mut self) -> Option<Self::Item> {
731        self.inner.next().map(|(_, v)| v)
732    }
733
734    fn size_hint(&self) -> (usize, Option<usize>) {
735        self.inner.size_hint()
736    }
737
738    fn count(self) -> usize {
739        self.inner.len()
740    }
741}
742
743impl<K, V> DoubleEndedIterator for IntoValues<K, V> {
744    fn next_back(&mut self) -> Option<Self::Item> {
745        self.inner.next_back().map(|(_, v)| v)
746    }
747}
748
749impl<K, V> ExactSizeIterator for IntoValues<K, V> {
750    fn len(&self) -> usize {
751        self.inner.len()
752    }
753}
754
755impl<K, V> FusedIterator for IntoValues<K, V> {}
756
757/// An iterator over a sub-range of entries in a [`FrozenMap`].
758pub struct Range<'a, K, V> {
759    inner: std::slice::Iter<'a, (K, V)>,
760}
761
762impl<K: Debug, V: Debug> Debug for Range<'_, K, V> {
763    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
764        f.debug_list().entries(self.clone()).finish()
765    }
766}
767
768impl<'a, K, V> Iterator for Range<'a, K, V> {
769    type Item = (&'a K, &'a V);
770
771    fn next(&mut self) -> Option<Self::Item> {
772        self.inner.next().map(|(k, v)| (k, v))
773    }
774
775    fn size_hint(&self) -> (usize, Option<usize>) {
776        self.inner.size_hint()
777    }
778
779    fn last(mut self) -> Option<Self::Item> {
780        self.next_back()
781    }
782
783    fn count(self) -> usize {
784        self.inner.len()
785    }
786}
787
788impl<K, V> DoubleEndedIterator for Range<'_, K, V> {
789    fn next_back(&mut self) -> Option<Self::Item> {
790        self.inner.next_back().map(|(k, v)| (k, v))
791    }
792}
793
794impl<K, V> ExactSizeIterator for Range<'_, K, V> {
795    fn len(&self) -> usize {
796        self.inner.len()
797    }
798}
799
800impl<K, V> FusedIterator for Range<'_, K, V> {}
801
802// Manual implementation because the derive would add unnecessary `K: Clone, V: Clone` type bounds.
803impl<K, V> Clone for Range<'_, K, V> {
804    fn clone(&self) -> Self {
805        Self {
806            inner: self.inner.clone(),
807        }
808    }
809}
810
811#[cfg(test)]
812mod tests {
813    use super::*;
814
815    #[test]
816    fn test_empty() {
817        let map = FrozenMap::<i32, i32>::new();
818        assert!(map.is_empty());
819        assert_eq!(map.len(), 0);
820        assert_eq!(map.get(&1), None);
821    }
822
823    #[test]
824    fn test_from_btreemap() {
825        let mut btree = BTreeMap::new();
826        btree.insert(3, "c");
827        btree.insert(1, "a");
828        btree.insert(2, "b");
829
830        let frozen = FrozenMap::from(btree);
831        assert_eq!(frozen.len(), 3);
832        assert_eq!(frozen.get(&1), Some(&"a"));
833        assert_eq!(frozen.get(&2), Some(&"b"));
834        assert_eq!(frozen.get(&3), Some(&"c"));
835
836        let keys: Vec<_> = frozen.keys().copied().collect();
837        assert_eq!(keys, vec![1, 2, 3]);
838    }
839
840    #[test]
841    fn test_from_overlapping_vec() {
842        let frozen = FrozenMap::from(vec![(1, "a"), (1, "b"), (2, "c")]);
843        assert_eq!(frozen.len(), 2);
844        // Last value wins for overlapping keys
845        assert_eq!(frozen.get(&1), Some(&"b"));
846        assert_eq!(frozen.get(&2), Some(&"c"));
847    }
848
849    #[test]
850    fn test_range() {
851        let frozen = FrozenMap::from([(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e")]);
852
853        let range: Vec<_> = frozen.range(2..4).collect();
854        assert_eq!(range, vec![(&2, &"b"), (&3, &"c")]);
855
856        let range: Vec<_> = frozen.range(2..=4).collect();
857        assert_eq!(range, vec![(&2, &"b"), (&3, &"c"), (&4, &"d")]);
858
859        let range: Vec<_> = frozen.range(..3).collect();
860        assert_eq!(range, vec![(&1, &"a"), (&2, &"b")]);
861    }
862
863    #[test]
864    fn test_index() {
865        let frozen = FrozenMap::from([(1, "a"), (2, "b")]);
866        assert_eq!(frozen[&1], "a");
867        assert_eq!(frozen[&2], "b");
868    }
869
870    #[test]
871    #[should_panic(expected = "no entry found for key")]
872    fn test_index_missing() {
873        let frozen = FrozenMap::from([(1, "a")]);
874        let _ = frozen[&2];
875    }
876
877    #[test]
878    fn test_first_last() {
879        let frozen = FrozenMap::from([(2, "b"), (1, "a"), (3, "c")]);
880        assert_eq!(frozen.first_key_value(), Some((&1, &"a")));
881        assert_eq!(frozen.last_key_value(), Some((&3, &"c")));
882
883        let empty = FrozenMap::<i32, i32>::new();
884        assert_eq!(empty.first_key_value(), None);
885        assert_eq!(empty.last_key_value(), None);
886    }
887
888    #[test]
889    fn test_as_ref() {
890        let frozen = FrozenMap::from([(2, "b"), (1, "a"), (3, "c")]);
891        let slice: &[(i32, &str)] = frozen.as_ref();
892        assert_eq!(slice, &[(1, "a"), (2, "b"), (3, "c")]);
893
894        let empty = FrozenMap::<i32, i32>::new();
895        let empty_slice: &[(i32, i32)] = empty.as_ref();
896        assert_eq!(empty_slice, &[]);
897    }
898
899    #[test]
900    fn test_from_hashmap() {
901        let mut map = HashMap::new();
902        map.insert(3, "c");
903        map.insert(1, "a");
904        map.insert(2, "b");
905
906        let frozen = FrozenMap::from(map);
907        assert_eq!(frozen.len(), 3);
908        assert_eq!(frozen.get(&1), Some(&"a"));
909        let keys: Vec<_> = frozen.keys().copied().collect();
910        assert_eq!(keys, vec![1, 2, 3]);
911    }
912
913    #[test]
914    fn test_from_unique_sorted_box() {
915        let frozen = FrozenMap::from_unique_sorted_box(Box::from([(1, "a"), (2, "b")]));
916        assert_eq!(frozen.len(), 2);
917        assert_eq!(frozen.get(&1), Some(&"a"));
918        assert_eq!(frozen.get(&2), Some(&"b"));
919    }
920
921    #[test]
922    #[should_panic(expected = "FrozenMap entries must be unique and sorted")]
923    fn test_from_unique_sorted_box_panics() {
924        let _ = FrozenMap::from_unique_sorted_box(Box::from([(1, "a"), (1, "b")]));
925    }
926}