1use core::{
2 borrow::Borrow,
3 fmt::Debug,
4 hash::Hash,
5 marker::PhantomData,
6 mem::MaybeUninit,
7 ops::{Index, IndexMut},
8};
9
10use generic_array::{
11 ArrayLength, GenericArray, GenericArrayIter, functional::FunctionalSequence,
12 sequence::GenericSequence, typenum::Unsigned,
13};
14
15use crate::{
16 IterAll,
17 finite::{Finite, FiniteExt},
18};
19
20#[repr(transparent)]
49pub struct ExhaustiveMap<K: Finite, V> {
50 array: GenericArray<V, K::INHABITANTS>,
51 _phantom: PhantomData<fn(&K) -> usize>,
52}
53
54impl<K: Finite, V> ExhaustiveMap<K, V> {
55 #[must_use]
59 pub fn from_fn(f: impl FnMut(K) -> V) -> Self {
60 Self {
61 array: K::iter_all().map(f).collect(),
62 _phantom: PhantomData,
63 }
64 }
65
66 pub fn try_from_fn<E>(f: impl FnMut(K) -> Result<V, E>) -> Result<Self, E> {
73 Ok(Self {
74 array: K::iter_all().map(f).collect::<Result<_, E>>()?,
75 _phantom: PhantomData,
76 })
77 }
78
79 #[must_use]
98 pub fn from_usize_fn(f: impl FnMut(usize) -> V) -> Self {
99 Self {
100 array: GenericArray::generate(f),
101 _phantom: PhantomData,
102 }
103 }
104
105 #[must_use]
109 pub const fn len(&self) -> usize {
110 K::INHABITANTS::USIZE
111 }
112
113 #[must_use]
118 pub const fn is_empty(&self) -> bool {
119 self.len() == 0
120 }
121
122 pub fn replace<Q: Borrow<K>>(&mut self, k: Q, v: V) -> V {
125 core::mem::replace(&mut self[k], v)
126 }
127
128 pub fn swap<Q1: Borrow<K>, Q2: Borrow<K>>(&mut self, k1: Q1, k2: Q2) {
130 self.array
131 .swap(k1.borrow().to_usize(), k2.borrow().to_usize());
132 }
133
134 pub fn take<Q: Borrow<K>>(&mut self, k: Q) -> V
137 where
138 V: Default,
139 {
140 core::mem::take(&mut self[k])
141 }
142
143 #[must_use]
155 pub fn map_values<U>(self, f: impl FnMut(V) -> U) -> ExhaustiveMap<K, U> {
156 ExhaustiveMap {
157 array: self.array.map(f),
158 _phantom: PhantomData,
159 }
160 }
161
162 pub fn keys() -> IterAll<K> {
167 K::iter_all()
168 }
169
170 pub fn values(&self) -> Values<'_, V> {
173 Values(self.array.iter())
174 }
175
176 pub fn values_mut(&mut self) -> ValuesMut<'_, V> {
179 ValuesMut(self.array.iter_mut())
180 }
181
182 pub fn into_values(self) -> IntoValues<V, K::INHABITANTS> {
186 IntoValues(self.array.into_iter())
187 }
188
189 pub fn iter(&self) -> Iter<'_, K, V> {
195 Iter(Self::keys().zip(self.values()))
196 }
197
198 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
204 IterMut(Self::keys().zip(self.values_mut()))
205 }
206
207 #[must_use]
213 pub fn new_uninit() -> ExhaustiveMap<K, MaybeUninit<V>> {
214 ExhaustiveMap {
215 array: GenericArray::uninit(),
216 _phantom: PhantomData,
217 }
218 }
219}
220
221impl<K: Finite, V> ExhaustiveMap<K, Option<V>> {
222 pub fn try_unwrap_values(self) -> Result<ExhaustiveMap<K, V>, ExhaustiveMap<K, Option<V>>> {
230 if !self.array.iter().all(Option::is_some) {
231 return Err(self);
232 }
233 #[allow(clippy::missing_panics_doc)]
234 Ok(self.map_values(|v| v.unwrap()))
235 }
236}
237
238impl<K: Finite, V> ExhaustiveMap<K, MaybeUninit<V>> {
239 #[must_use]
243 pub unsafe fn assume_init(self) -> ExhaustiveMap<K, V> {
244 ExhaustiveMap {
245 array: unsafe { GenericArray::assume_init(self.array) },
247 _phantom: PhantomData,
248 }
249 }
250}
251
252#[cfg(feature = "alloc")]
253mod alloc_impls {
254 use alloc::{boxed::Box, collections::BTreeMap, vec::Vec};
255 use core::marker::PhantomData;
256
257 use crate::{ExhaustiveMap, Finite, generic_array::GenericArray, typenum::Unsigned};
258
259 impl<K: Finite, V> TryFrom<Box<[V]>> for ExhaustiveMap<K, V> {
260 type Error = Box<[V]>;
261
262 fn try_from(value: Box<[V]>) -> Result<Self, Self::Error> {
263 if value.len() != K::INHABITANTS::USIZE {
264 return Err(value);
265 }
266 Ok(Self {
267 array: *GenericArray::try_from_boxed_slice(value).unwrap(),
268 _phantom: PhantomData,
269 })
270 }
271 }
272
273 impl<K: Finite, V> From<ExhaustiveMap<K, V>> for Box<[V]> {
274 fn from(value: ExhaustiveMap<K, V>) -> Self {
275 Box::new(value.array).into_boxed_slice()
276 }
277 }
278
279 impl<K: Finite, V> TryFrom<Vec<V>> for ExhaustiveMap<K, V> {
280 type Error = Vec<V>;
281
282 fn try_from(value: Vec<V>) -> Result<Self, Self::Error> {
283 if value.len() != K::INHABITANTS::USIZE {
284 return Err(value);
285 }
286 Ok(Self {
287 array: *GenericArray::try_from_vec(value).unwrap(),
288 _phantom: PhantomData,
289 })
290 }
291 }
292
293 impl<const N: usize, K: Finite, V> TryFrom<[V; N]> for ExhaustiveMap<K, V> {
294 type Error = [V; N];
295
296 fn try_from(value: [V; N]) -> Result<Self, Self::Error> {
297 if N != K::INHABITANTS::USIZE {
298 return Err(value);
299 }
300 Ok(Self {
301 array: GenericArray::try_from_iter(value).unwrap(),
302 _phantom: PhantomData,
303 })
304 }
305 }
306
307 impl<K: Finite + Ord, V> TryFrom<BTreeMap<K, V>> for ExhaustiveMap<K, V> {
308 type Error = K;
309
310 fn try_from(mut value: BTreeMap<K, V>) -> Result<Self, Self::Error> {
311 Self::try_from_fn(|k| value.remove(&k).ok_or(k))
312 }
313 }
314
315 impl<K: Finite + Ord, V> From<ExhaustiveMap<K, V>> for BTreeMap<K, V> {
316 fn from(value: ExhaustiveMap<K, V>) -> Self {
317 Self::from_iter(value)
318 }
319 }
320}
321
322#[cfg(feature = "std")]
323mod std_impls {
324 use std::{
325 collections::HashMap,
326 hash::{BuildHasher, Hash},
327 };
328
329 use crate::{ExhaustiveMap, Finite};
330
331 impl<K: Finite + Eq + Hash, V> TryFrom<HashMap<K, V>> for ExhaustiveMap<K, V> {
332 type Error = K;
333
334 fn try_from(mut value: HashMap<K, V>) -> Result<Self, Self::Error> {
335 Self::try_from_fn(|k| value.remove(&k).ok_or(k))
336 }
337 }
338
339 impl<K: Finite + Eq + Hash, V, S: BuildHasher + Default> From<ExhaustiveMap<K, V>>
340 for HashMap<K, V, S>
341 {
342 fn from(value: ExhaustiveMap<K, V>) -> Self {
343 Self::from_iter(value)
344 }
345 }
346}
347
348#[must_use = "iterators are lazy and do nothing unless consumed"]
352pub struct Values<'a, V>(core::slice::Iter<'a, V>);
353
354impl<'a, V> Iterator for Values<'a, V> {
355 type Item = &'a V;
356
357 fn next(&mut self) -> Option<Self::Item> {
358 self.0.next()
359 }
360
361 fn size_hint(&self) -> (usize, Option<usize>) {
362 (self.0.len(), Some(self.0.len()))
363 }
364}
365
366impl<T> ExactSizeIterator for Values<'_, T> {
367 fn len(&self) -> usize {
368 self.0.len()
369 }
370}
371
372impl<T> DoubleEndedIterator for Values<'_, T> {
373 fn next_back(&mut self) -> Option<Self::Item> {
374 self.0.next_back()
375 }
376}
377
378#[must_use = "iterators are lazy and do nothing unless consumed"]
382pub struct ValuesMut<'a, V>(core::slice::IterMut<'a, V>);
383
384impl<'a, V> Iterator for ValuesMut<'a, V> {
385 type Item = &'a mut V;
386
387 fn next(&mut self) -> Option<Self::Item> {
388 self.0.next()
389 }
390
391 fn size_hint(&self) -> (usize, Option<usize>) {
392 (self.0.len(), Some(self.0.len()))
393 }
394}
395
396impl<T> ExactSizeIterator for ValuesMut<'_, T> {
397 fn len(&self) -> usize {
398 self.0.len()
399 }
400}
401
402impl<T> DoubleEndedIterator for ValuesMut<'_, T> {
403 fn next_back(&mut self) -> Option<Self::Item> {
404 self.0.next_back()
405 }
406}
407
408#[must_use = "iterators are lazy and do nothing unless consumed"]
412pub struct IntoValues<V, N: ArrayLength>(GenericArrayIter<V, N>);
413
414impl<V, N: ArrayLength> Iterator for IntoValues<V, N> {
415 type Item = V;
416
417 fn next(&mut self) -> Option<Self::Item> {
418 self.0.next()
419 }
420
421 fn size_hint(&self) -> (usize, Option<usize>) {
422 (self.0.len(), Some(self.0.len()))
423 }
424}
425
426impl<V, N: ArrayLength> ExactSizeIterator for IntoValues<V, N> {
427 fn len(&self) -> usize {
428 self.0.len()
429 }
430}
431
432impl<V, N: ArrayLength> DoubleEndedIterator for IntoValues<V, N> {
433 fn next_back(&mut self) -> Option<Self::Item> {
434 self.0.next_back()
435 }
436}
437
438impl<K: Finite, V: Default> Default for ExhaustiveMap<K, V> {
439 fn default() -> Self {
440 Self {
441 array: GenericArray::default(),
442 _phantom: PhantomData,
443 }
444 }
445}
446
447#[must_use = "iterators are lazy and do nothing unless consumed"]
451pub struct Iter<'a, K, V>(core::iter::Zip<IterAll<K>, Values<'a, V>>);
452
453impl<'a, K, V> Iterator for Iter<'a, K, V> {
454 type Item = (K, &'a V);
455
456 fn next(&mut self) -> Option<Self::Item> {
457 self.0.next()
458 }
459
460 fn size_hint(&self) -> (usize, Option<usize>) {
461 (self.0.len(), Some(self.0.len()))
462 }
463}
464
465impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
466 fn len(&self) -> usize {
467 self.0.len()
468 }
469}
470
471impl<K, V> DoubleEndedIterator for Iter<'_, K, V> {
472 fn next_back(&mut self) -> Option<Self::Item> {
473 self.0.next_back()
474 }
475}
476
477#[must_use = "iterators are lazy and do nothing unless consumed"]
481pub struct IterMut<'a, K, V>(core::iter::Zip<IterAll<K>, ValuesMut<'a, V>>);
482
483impl<'a, K, V> Iterator for IterMut<'a, K, V> {
484 type Item = (K, &'a mut V);
485
486 fn next(&mut self) -> Option<Self::Item> {
487 self.0.next()
488 }
489
490 fn size_hint(&self) -> (usize, Option<usize>) {
491 (self.0.len(), Some(self.0.len()))
492 }
493}
494
495impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
496 fn len(&self) -> usize {
497 self.0.len()
498 }
499}
500
501impl<K, V> DoubleEndedIterator for IterMut<'_, K, V> {
502 fn next_back(&mut self) -> Option<Self::Item> {
503 self.0.next_back()
504 }
505}
506
507#[must_use = "iterators are lazy and do nothing unless consumed"]
512pub struct IntoIter<K: Finite, V>(core::iter::Zip<IterAll<K>, IntoValues<V, K::INHABITANTS>>);
513
514impl<K: Finite, V> Iterator for IntoIter<K, V> {
515 type Item = (K, V);
516
517 fn next(&mut self) -> Option<Self::Item> {
518 self.0.next()
519 }
520
521 fn size_hint(&self) -> (usize, Option<usize>) {
522 (self.0.len(), Some(self.0.len()))
523 }
524}
525
526impl<K: Finite, V> ExactSizeIterator for IntoIter<K, V> {
527 fn len(&self) -> usize {
528 self.0.len()
529 }
530}
531
532impl<K: Finite, V> DoubleEndedIterator for IntoIter<K, V> {
533 fn next_back(&mut self) -> Option<Self::Item> {
534 self.0.next_back()
535 }
536}
537
538impl<K: Finite, V> IntoIterator for ExhaustiveMap<K, V> {
539 type Item = (K, V);
540
541 type IntoIter = IntoIter<K, V>;
542
543 fn into_iter(self) -> Self::IntoIter {
544 IntoIter(Self::keys().zip(self.into_values()))
545 }
546}
547
548impl<'a, K: Finite, V> IntoIterator for &'a ExhaustiveMap<K, V> {
549 type Item = (K, &'a V);
550
551 type IntoIter = Iter<'a, K, V>;
552
553 fn into_iter(self) -> Self::IntoIter {
554 self.iter()
555 }
556}
557
558impl<'a, K: Finite, V> IntoIterator for &'a mut ExhaustiveMap<K, V> {
559 type Item = (K, &'a mut V);
560
561 type IntoIter = IterMut<'a, K, V>;
562
563 fn into_iter(self) -> Self::IntoIter {
564 self.iter_mut()
565 }
566}
567
568impl<K: Finite + Debug, V: Debug> Debug for ExhaustiveMap<K, V> {
569 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
570 f.debug_map().entries(self).finish()
571 }
572}
573
574impl<K: Finite, V, Q: Borrow<K>> Index<Q> for ExhaustiveMap<K, V> {
575 type Output = V;
576
577 fn index(&self, index: Q) -> &Self::Output {
578 &self.array[K::to_usize(index.borrow())]
579 }
580}
581
582impl<K: Finite, V, Q: Borrow<K>> IndexMut<Q> for ExhaustiveMap<K, V> {
583 fn index_mut(&mut self, index: Q) -> &mut Self::Output {
584 &mut self.array[K::to_usize(index.borrow())]
585 }
586}
587
588impl<K: Finite, V: Clone> Clone for ExhaustiveMap<K, V> {
592 fn clone(&self) -> Self {
593 Self {
594 array: self.array.clone(),
595 _phantom: PhantomData,
596 }
597 }
598}
599
600impl<K: Finite, V: Copy> Copy for ExhaustiveMap<K, V> where GenericArray<V, K::INHABITANTS>: Copy {}
601
602impl<K: Finite, V: PartialEq> PartialEq for ExhaustiveMap<K, V> {
603 fn eq(&self, other: &Self) -> bool {
604 self.array.eq(&other.array)
605 }
606}
607
608impl<K: Finite, V: Eq> Eq for ExhaustiveMap<K, V> {}
609
610impl<K: Finite, V: PartialOrd> PartialOrd for ExhaustiveMap<K, V> {
611 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
612 self.array.partial_cmp(&other.array)
613 }
614}
615
616impl<K: Finite, V: Ord> Ord for ExhaustiveMap<K, V> {
617 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
618 self.array.cmp(&other.array)
619 }
620}
621
622impl<K: Finite, V: Hash> Hash for ExhaustiveMap<K, V> {
623 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
624 self.array.hash(state);
625 }
626}
627
628#[cfg(feature = "serde")]
629mod serde_impl {
630 use alloc::format;
631 use core::{any::type_name, marker::PhantomData};
632
633 use generic_array::typenum::Unsigned;
634 use serde::{
635 Deserialize, Deserializer, Serialize, Serializer,
636 de::{Error, Visitor},
637 ser::SerializeMap,
638 };
639
640 use super::{ExhaustiveMap, Finite};
641
642 impl<K: Finite + Serialize, V: Serialize> Serialize for ExhaustiveMap<K, V> {
643 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
644 where
645 S: Serializer,
646 {
647 let mut map = serializer.serialize_map(Some(K::INHABITANTS::USIZE))?;
648 for (k, v) in self {
649 map.serialize_entry(&k, v)?;
650 }
651 map.end()
652 }
653 }
654
655 struct MapVisitor<K: Finite, V>(PhantomData<fn() -> ExhaustiveMap<K, V>>);
656 impl<K: Finite, V> MapVisitor<K, V> {
657 fn new() -> Self {
658 Self(PhantomData)
659 }
660 }
661
662 impl<'de, K: Finite + Deserialize<'de>, V: Deserialize<'de>> Visitor<'de> for MapVisitor<K, V> {
663 type Value = ExhaustiveMap<K, V>;
664
665 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
666 write!(
667 formatter,
668 "an ExhaustiveMap<{}, {}>",
669 type_name::<K>(),
670 type_name::<V>()
671 )
672 }
673
674 fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
675 where
676 A: serde::de::MapAccess<'de>,
677 {
678 let mut map: ExhaustiveMap<K, Option<V>> = ExhaustiveMap::default();
679
680 while let Some((key, value)) = access.next_entry::<K, V>()? {
681 map[key] = Some(value);
682 }
683
684 let map = map.try_unwrap_values().map_err(|e| {
685 A::Error::custom(format!(
686 "ExhaustiveMap<{}, {}>: found entries for {} keys out of {} keys",
687 type_name::<K>(),
688 type_name::<V>(),
689 e.values().filter(|v| v.is_some()).count(),
690 K::INHABITANTS::USIZE,
691 ))
692 })?;
693 Ok(map)
694 }
695 }
696
697 impl<'de, K: Finite + Deserialize<'de>, V: Deserialize<'de>> serde::Deserialize<'de>
698 for ExhaustiveMap<K, V>
699 {
700 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
701 where
702 D: Deserializer<'de>,
703 {
704 deserializer.deserialize_map(MapVisitor::new())
705 }
706 }
707
708 #[cfg(test)]
709 mod test {
710 use alloc::string::ToString;
711
712 use super::*;
713
714 #[derive(Debug, Finite, Serialize, Deserialize)]
715 enum Color {
716 Red,
717 Green,
718 Blue,
719 }
720
721 #[test]
722 fn test_serialize_deserialize() {
723 let map = ExhaustiveMap::<Color, _>::from_usize_fn(|i| i);
724 let json = serde_json::to_string(&map).unwrap();
725 assert_eq!(json, r#"{"Red":0,"Green":1,"Blue":2}"#);
726
727 let deserialized: ExhaustiveMap<Color, usize> = serde_json::from_str(&json).unwrap();
728 assert_eq!(deserialized, map);
729 }
730
731 #[test]
732 fn test_deserialize_missing_entry() {
733 let json = r#"{"Red":0,"Blue":2}"#;
734
735 let err = serde_json::from_str::<ExhaustiveMap<Color, usize>>(&json).unwrap_err();
736 assert!(
737 err.to_string()
738 .contains("found entries for 2 keys out of 3 key"),
739 "{err:?}"
740 );
741 }
742 }
743}
744
745#[cfg(all(test, feature = "std"))]
746mod test {
747 use std::{prelude::rust_2024::*, println};
748
749 use super::*;
750
751 #[derive(Finite)]
752 struct Key(PhantomData<*mut u8>);
753
754 #[allow(unused)]
755 const fn assert_implements_traits<
756 T: Send + Sync + Default + Clone + Copy + PartialEq + Eq + PartialOrd + Ord + Hash,
757 >() {
758 }
759
760 const _: () = assert_implements_traits::<ExhaustiveMap<Key, bool>>();
761
762 #[test]
763 fn test_uninit() {
764 let mut m = ExhaustiveMap::<bool, u8>::new_uninit();
765 m[true].write(123);
766 m[false].write(45);
767 let m = unsafe { m.assume_init() };
769 println!("{m:?}");
770 }
771
772 #[test]
773 fn test_conversion() {
774 let m: ExhaustiveMap<bool, u8> = [2, 3].try_into().unwrap();
775 assert_eq!(m[false], 2);
776 assert_eq!(m[true], 3);
777 }
778
779 #[test]
780 fn test_try_unrwap_values() {
781 let m: ExhaustiveMap<bool, Option<u8>> = ExhaustiveMap::from_fn(|_| None);
782 let mut m = m.try_unwrap_values().unwrap_err();
783 m[false] = Some(2);
784 let mut m = m.try_unwrap_values().unwrap_err();
785 m[true] = Some(3);
786 let m = m.try_unwrap_values().unwrap();
787 let expected = ExhaustiveMap::from_fn(|v| if v { 3 } else { 2 });
788 assert_eq!(m, expected);
789 }
790}