enum_table/
impls.rs

1use std::ops::{Index, IndexMut};
2
3use crate::{EnumTable, Enumable};
4
5impl<K: Enumable + core::fmt::Debug, V: core::fmt::Debug, const N: usize> core::fmt::Debug
6    for EnumTable<K, V, N>
7{
8    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
9        f.debug_map().entries(self.iter()).finish()
10    }
11}
12
13impl<K: Enumable, V: Clone, const N: usize> Clone for EnumTable<K, V, N> {
14    fn clone(&self) -> Self {
15        Self {
16            table: self.table.clone(),
17            _phantom: core::marker::PhantomData,
18        }
19    }
20}
21
22impl<K: Enumable, V: PartialEq, const N: usize> PartialEq for EnumTable<K, V, N> {
23    fn eq(&self, other: &Self) -> bool {
24        self.table.eq(&other.table)
25    }
26}
27
28impl<K: Enumable, V: Eq, const N: usize> Eq for EnumTable<K, V, N> {}
29
30impl<K: Enumable, V: std::hash::Hash, const N: usize> std::hash::Hash for EnumTable<K, V, N> {
31    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
32        self.table.hash(state);
33    }
34}
35
36impl<K: Enumable, V: Default, const N: usize> Default for EnumTable<K, V, N> {
37    fn default() -> Self {
38        EnumTable::new_with_fn(|_| Default::default())
39    }
40}
41
42impl<K: Enumable, V, const N: usize> Index<K> for EnumTable<K, V, N> {
43    type Output = V;
44
45    fn index(&self, index: K) -> &Self::Output {
46        self.get(&index)
47    }
48}
49
50impl<K: Enumable, V, const N: usize> IndexMut<K> for EnumTable<K, V, N> {
51    fn index_mut(&mut self, index: K) -> &mut Self::Output {
52        self.get_mut(&index)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use std::hash::{Hash, Hasher};
59
60    use super::*;
61
62    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
63    enum Color {
64        Red,
65        Green,
66        Blue,
67    }
68
69    impl Enumable for Color {
70        const VARIANTS: &'static [Self] = &[Color::Red, Color::Green, Color::Blue];
71    }
72
73    const TABLES: EnumTable<Color, &'static str, { Color::COUNT }> =
74        crate::et!(Color, &'static str, |color| match color {
75            Color::Red => "Red",
76            Color::Green => "Green",
77            Color::Blue => "Blue",
78        });
79
80    const ANOTHER_TABLES: EnumTable<Color, &'static str, { Color::COUNT }> =
81        crate::et!(Color, &'static str, |color| match color {
82            Color::Red => "Red",
83            Color::Green => "Green",
84            Color::Blue => "Blue",
85        });
86
87    #[test]
88    fn debug_impl() {
89        assert_eq!(
90            format!("{:?}", TABLES),
91            r#"{Red: "Red", Green: "Green", Blue: "Blue"}"#
92        );
93    }
94
95    #[test]
96    fn clone_impl() {
97        let cloned = TABLES.clone();
98        assert_eq!(cloned, TABLES);
99    }
100
101    #[test]
102    fn eq_impl() {
103        assert!(TABLES == ANOTHER_TABLES);
104        assert!(TABLES != EnumTable::new_with_fn(|_| "Unknown"));
105    }
106
107    #[test]
108    fn hash_impl() {
109        let mut hasher = std::collections::hash_map::DefaultHasher::new();
110        TABLES.hash(&mut hasher);
111        let hash1 = hasher.finish();
112
113        let mut hasher2 = std::collections::hash_map::DefaultHasher::new();
114        ANOTHER_TABLES.hash(&mut hasher2);
115        let hash2 = hasher2.finish();
116
117        assert_eq!(hash1, hash2);
118    }
119
120    #[test]
121    fn default_impl() {
122        let default_table: EnumTable<Color, &'static str, { Color::COUNT }> = EnumTable::default();
123        assert_eq!(default_table.get(&Color::Red), &"");
124        assert_eq!(default_table.get(&Color::Green), &"");
125        assert_eq!(default_table.get(&Color::Blue), &"");
126    }
127
128    #[test]
129    fn index_impl() {
130        assert_eq!(TABLES[Color::Red], "Red");
131        assert_eq!(TABLES[Color::Green], "Green");
132        assert_eq!(TABLES[Color::Blue], "Blue");
133
134        let mut mutable_table = TABLES.clone();
135        mutable_table[Color::Red] = "Changed Red";
136        assert_eq!(mutable_table[Color::Red], "Changed Red");
137    }
138}