exhaustive_map/
map.rs

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/// A map which is guaranteed to always contain a value for each possible key of
21/// type `K`.
22///
23/// ```
24/// use exhaustive_map::ExhaustiveMap;
25///
26/// let mut map = ExhaustiveMap::<u8, u16>::from_fn(|i| i as u16 + 100);
27/// assert_eq!(map.len(), 256);
28///
29/// assert_eq!(map[3], 103);
30///
31/// map[7] = 9999;
32/// assert_eq!(map[7], 9999);
33///
34/// map.swap(7, 3);
35/// assert_eq!(map[3], 9999);
36/// assert_eq!(map[7], 103);
37/// ```
38///
39/// # Layout
40///
41/// The layout of `ExhaustiveMap<K, V>` is guaranteed to be the same as `[V; N]`
42/// where `N` is the number of inhabitants of type `K`.
43///
44/// ```
45/// # use exhaustive_map::ExhaustiveMap;
46/// assert_eq!(size_of::<ExhaustiveMap<u8, bool>>(), 256);
47/// ```
48#[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    /// Creates a map by providing a mapping function from `K` to `V`.
56    ///
57    /// Similar to [`array::from_fn`](std::array::from_fn).
58    #[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    /// Tries to create a map by providing a mapping function from `K` to
67    /// `Result<V, E>`.
68    ///
69    /// # Errors
70    ///
71    /// Returns the first error if any of the mappings fails.
72    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    /// Creates a map by providing a mapping function from `usize` to `V`.
80    /// The map is filled according to the [`Finite`] implementation of `K`.
81    ///
82    /// ```
83    /// use exhaustive_map::{ExhaustiveMap, Finite};
84    ///
85    /// #[derive(Finite, Debug)]
86    /// enum Color {
87    ///     Red,
88    ///     Green,
89    ///     Blue,
90    /// }
91    ///
92    /// let map = ExhaustiveMap::from_usize_fn(|i| i);
93    /// assert_eq!(map[Color::Red], 0);
94    /// assert_eq!(map[Color::Green], 1);
95    /// assert_eq!(map[Color::Blue], 2);
96    /// ```
97    #[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    /// Returns the number of elements in the map.
106    ///
107    /// Always equal to `K::INHABITANTS::USIZE`.
108    #[must_use]
109    pub const fn len(&self) -> usize {
110        K::INHABITANTS::USIZE
111    }
112
113    /// Returns `true` if the map contains no elements.
114    ///
115    /// The map can only be empty if `K::INHABITANTS` is zero,
116    /// meaning the type `K` is uninhabitable.
117    #[must_use]
118    pub const fn is_empty(&self) -> bool {
119        self.len() == 0
120    }
121
122    /// Replace the value stored for `k` with `v`, returning the previous stored
123    /// value.
124    pub fn replace<Q: Borrow<K>>(&mut self, k: Q, v: V) -> V {
125        core::mem::replace(&mut self[k], v)
126    }
127
128    /// Swaps the values at stored at `k1` and `k2`.
129    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    /// Replace the value stored for `k` with the default value of `V`,
135    /// returning the previous stored value.
136    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    /// Change the values of the stored values via a mapping function.
144    ///
145    /// ```
146    /// use exhaustive_map::ExhaustiveMap;
147    ///
148    /// let bool_to_int = ExhaustiveMap::from_fn(|k| if k { 1 } else { 0 });
149    /// let bool_to_int_string = bool_to_int.map_values(|v| v.to_string());
150    ///
151    /// assert_eq!(bool_to_int_string[false], "0");
152    /// assert_eq!(bool_to_int_string[true], "1");
153    /// ```
154    #[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    /// An iterator visiting all keys in the order provided by [`Finite`].
163    ///
164    /// This creates new keys by calling [`K::from_usize`](Finite::from_usize)
165    /// for each key.
166    pub fn keys() -> IterAll<K> {
167        K::iter_all()
168    }
169
170    /// An iterator visiting all values stored in the map, ordered by the keys
171    /// order provided by [`Finite`].
172    pub fn values(&self) -> Values<'_, V> {
173        Values(self.array.iter())
174    }
175
176    /// A mutable iterator visiting all values stored in the map, ordered by the
177    /// keys order provided by [`Finite`].
178    pub fn values_mut(&mut self) -> ValuesMut<'_, V> {
179        ValuesMut(self.array.iter_mut())
180    }
181
182    /// Creates a consuming iterator visiting all the values, ordered by the
183    /// keys order provided by [`Finite`]. The map cannot be used after
184    /// calling this.
185    pub fn into_values(self) -> IntoValues<V, K::INHABITANTS> {
186        IntoValues(self.array.into_iter())
187    }
188
189    /// An iterator visiting all entries stored in the map, ordered by the keys
190    /// order provided by [`Finite`].
191    ///
192    /// This creates new keys by calling [`K::from_usize`](Finite::from_usize)
193    /// for each key.
194    pub fn iter(&self) -> Iter<'_, K, V> {
195        Iter(Self::keys().zip(self.values()))
196    }
197
198    /// A mutable iterator visiting all entries stored in the map, ordered by
199    /// the keys order provided by [`Finite`].
200    ///
201    /// This creates new keys by calling [`K::from_usize`](Finite::from_usize)
202    /// for each key.
203    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
204        IterMut(Self::keys().zip(self.values_mut()))
205    }
206
207    /// Creates a map with [`MaybeUninit`] values.
208    ///
209    /// After every value have been initialized
210    /// [`assume_init`](ExhaustiveMap::assume_init) can be called to obtain
211    /// a map with values of type `V`.
212    #[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    /// Tries to convert an `ExhaustiveMap<K, Option<V>>` to an
223    /// `ExhaustiveMap<K, V>`.
224    ///
225    /// # Errors
226    ///
227    /// If any of the values are `None`, this returns `Err` containing the input
228    /// map.
229    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    /// # Safety
240    ///
241    /// All elements must have been initialized.
242    #[must_use]
243    pub unsafe fn assume_init(self) -> ExhaustiveMap<K, V> {
244        ExhaustiveMap {
245            // SAFETY: caller ensures this
246            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/// An iterator over the values of an [`ExhaustiveMap`].
349///
350/// This `struct` is created by the [`ExhaustiveMap::values`] method.
351#[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/// A mutable iterator over the values of an [`ExhaustiveMap`].
379///
380/// This `struct` is created by the [`ExhaustiveMap::values_mut`] method.
381#[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/// An owning iterator over the values of an [`ExhaustiveMap`].
409///
410/// This `struct` is created by the [`ExhaustiveMap::into_values`] method.
411#[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/// An iterator over the entries of an [`ExhaustiveMap`].
448///
449/// This `struct` is created by the [`ExhaustiveMap::iter`] method.
450#[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/// A mutable iterator over the entries of an [`ExhaustiveMap`].
478///
479/// This `struct` is created by the [`ExhaustiveMap::iter_mut`] method.
480#[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/// An owning iterator over the entries of an [`ExhaustiveMap`].
508///
509/// This `struct` is created by the [`into_iter`](IntoIterator::into_iter)
510/// method on [`ExhaustiveMap`] (provided by the [`IntoIterator`] trait).
511#[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
588// The following traits could have been implemented using a derive macro,
589// however that would put an unnecessary trait bound on the key.
590
591impl<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        // SAFETY: All elements has been initialized.
768        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}