enum-collections 2.0.0

EnumMap implemented in safe rust
Documentation
use serde::{Deserialize, Serialize, de::Visitor};
use std::{any::type_name, marker::PhantomData};

use crate::{EnumMap, Enumerated};

impl<K: Enumerated + Serialize, V: Serialize, const N: usize> Serialize for EnumMap<K, V, N> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.collect_map(self.iter_kv())
    }
}

struct EnumMapVisitor<
    'de,
    K: Enumerated + Deserialize<'de> + PartialEq,
    V: Deserialize<'de> + Default,
    const N: usize,
> {
    marker: PhantomData<&'de (K, V)>,
}

impl<
    'de,
    K: Enumerated + Deserialize<'de> + PartialEq,
    V: Deserialize<'de> + Default,
    const N: usize,
> Visitor<'de> for EnumMapVisitor<'de, K, V, N>
{
    type Value = EnumMap<K, V, N>;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(
            formatter,
            "EnumMap<{}, {}>",
            type_name::<K>(),
            type_name::<V>()
        )
    }

    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
    where
        A: serde::de::MapAccess<'de>,
    {
        let mut data = std::array::from_fn(|_| V::default());
        while let Some((k, v)) = map.next_entry::<K, V>()? {
            data[k.position()] = v;
        }

        Ok(EnumMap {
            data,
            _key: PhantomData,
        })
    }
}

impl<
    'de,
    K: Enumerated + Deserialize<'de> + PartialEq,
    V: Deserialize<'de> + Default + 'de,
    const N: usize,
> Deserialize<'de> for EnumMap<K, V, N>
{
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let visitor = EnumMapVisitor {
            marker: PhantomData,
        };
        deserializer.deserialize_map(visitor)
    }
}