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#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode, Serialize, Deserialize)]
42#[rustfmt::skip] #[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 pub(crate) entries: Box<[(K, V)]>,
50}
51
52impl<K, V> FrozenMap<K, V> {
53 pub fn new() -> Self {
55 FrozenMap {
56 entries: Box::from([]),
60 }
61 }
62}
63
64impl<K, V> FrozenMap<K, V>
65where
66 K: Ord,
67{
68 pub fn from_unique_sorted_box(entries: Box<[(K, V)]>) -> Self {
72 assert_unique_sorted(&entries);
73 FrozenMap { entries }
74 }
75
76 pub fn from_unique_sorted_box_unchecked(entries: Box<[(K, V)]>) -> Self {
90 debug_assert_unique_sorted(&entries);
91 FrozenMap { entries }
92 }
93
94 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 pub(crate) fn from_vec_inner(mut entries: Vec<(K, V)>) -> Self {
106 entries.sort_by(|a, b| a.0.cmp(&b.0));
108 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 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 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 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 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 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 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 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 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 pub const fn len(&self) -> usize {
251 self.entries.len()
252 }
253
254 pub const fn is_empty(&self) -> bool {
256 self.entries.is_empty()
257 }
258
259 pub const fn as_slice(&self) -> &[(K, V)] {
261 &self.entries
262 }
263
264 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 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 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 pub fn first_key_value(&self) -> Option<(&K, &V)> {
300 self.entries.first().map(|(k, v)| (k, v))
301 }
302
303 pub fn last_key_value(&self) -> Option<(&K, &V)> {
305 self.entries.last().map(|(k, v)| (k, v))
306 }
307
308 pub fn iter(&self) -> Iter<'_, K, V> {
310 Iter {
311 inner: self.entries.iter(),
312 }
313 }
314
315 pub fn keys(&self) -> Keys<'_, K, V> {
317 Keys { inner: self.iter() }
318 }
319
320 pub fn values(&self) -> Values<'_, K, V> {
322 Values { inner: self.iter() }
323 }
324
325 pub fn into_keys(self) -> IntoKeys<K, V> {
327 IntoKeys {
328 inner: self.into_iter(),
329 }
330 }
331
332 pub fn into_values(self) -> IntoValues<K, V> {
334 IntoValues {
335 inner: self.into_iter(),
336 }
337 }
338
339 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 #[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
397impl<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
454pub 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
509impl<K, V> Clone for Iter<'_, K, V> {
511 fn clone(&self) -> Self {
512 Self {
513 inner: self.inner.clone(),
514 }
515 }
516}
517
518pub 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
559pub 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
606impl<K, V> Clone for Keys<'_, K, V> {
608 fn clone(&self) -> Self {
609 Self {
610 inner: self.inner.clone(),
611 }
612 }
613}
614
615pub 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
662impl<K, V> Clone for Values<'_, K, V> {
664 fn clone(&self) -> Self {
665 Self {
666 inner: self.inner.clone(),
667 }
668 }
669}
670
671pub 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
714pub 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
757pub 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
802impl<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 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}