Skip to main content

enum_table/impls/
core.rs

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