Skip to main content

enum_table/impls/
core.rs

1use core::marker::PhantomData;
2use core::ops::{Index, IndexMut};
3
4use crate::{EnumTable, Enumable};
5
6impl<K: Enumable + 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: Enumable, 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: Enumable, V: Copy, const N: usize> Copy for EnumTable<K, V, N> {}
24
25impl<K: Enumable, 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: Enumable, V: Eq, const N: usize> Eq for EnumTable<K, V, N> {}
32
33impl<K: Enumable, V: core::hash::Hash, const N: usize> core::hash::Hash
34    for EnumTable<K, V, N>
35{
36    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
37        self.table.hash(state);
38    }
39}
40
41impl<K: Enumable, V: Default, const N: usize> Default for EnumTable<K, V, N> {
42    fn default() -> Self {
43        Self::new_fill_with_default()
44    }
45}
46
47impl<K: Enumable, V, const N: usize> Index<K> for EnumTable<K, V, N> {
48    type Output = V;
49
50    fn index(&self, index: K) -> &Self::Output {
51        self.get(&index)
52    }
53}
54
55impl<K: Enumable, V, const N: usize> IndexMut<K> for EnumTable<K, V, N> {
56    fn index_mut(&mut self, index: K) -> &mut Self::Output {
57        self.get_mut(&index)
58    }
59}
60
61impl<K: Enumable, V, const N: usize> Index<&K> for EnumTable<K, V, N> {
62    type Output = V;
63
64    fn index(&self, index: &K) -> &Self::Output {
65        self.get(index)
66    }
67}
68
69impl<K: Enumable, V, const N: usize> IndexMut<&K> for EnumTable<K, V, N> {
70    fn index_mut(&mut self, index: &K) -> &mut Self::Output {
71        self.get_mut(index)
72    }
73}
74
75impl<K: Enumable, V, const N: usize> AsRef<[V]> for EnumTable<K, V, N> {
76    fn as_ref(&self) -> &[V] {
77        self.as_slice()
78    }
79}
80
81impl<K: Enumable, V, const N: usize> AsMut<[V]> for EnumTable<K, V, N> {
82    fn as_mut(&mut self) -> &mut [V] {
83        self.as_mut_slice()
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use core::hash::{Hash, Hasher};
90
91    use super::*;
92
93    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Enumable)]
94    enum Color {
95        Red,
96        Green,
97        Blue,
98    }
99
100    const TABLES: EnumTable<Color, &'static str, { Color::COUNT }> =
101        crate::et!(Color, &'static str, |color| match color {
102            Color::Red => "Red",
103            Color::Green => "Green",
104            Color::Blue => "Blue",
105        });
106
107    const ANOTHER_TABLES: EnumTable<Color, &'static str, { Color::COUNT }> =
108        crate::et!(Color, &'static str, |color| match color {
109            Color::Red => "Red",
110            Color::Green => "Green",
111            Color::Blue => "Blue",
112        });
113
114    #[test]
115    fn debug_impl() {
116        assert_eq!(
117            format!("{TABLES:?}"),
118            r#"{Red: "Red", Green: "Green", Blue: "Blue"}"#
119        );
120    }
121
122    #[test]
123    fn eq_impl() {
124        assert!(TABLES == ANOTHER_TABLES);
125        assert!(TABLES != EnumTable::new_with_fn(|_| "Unknown"));
126    }
127
128    #[test]
129    fn hash_impl() {
130        let mut hasher = std::collections::hash_map::DefaultHasher::new();
131        TABLES.hash(&mut hasher);
132        let hash1 = hasher.finish();
133
134        let mut hasher2 = std::collections::hash_map::DefaultHasher::new();
135        ANOTHER_TABLES.hash(&mut hasher2);
136        let hash2 = hasher2.finish();
137
138        assert_eq!(hash1, hash2);
139    }
140
141    #[test]
142    fn default_impl() {
143        let default_table: EnumTable<Color, &'static str, { Color::COUNT }> = EnumTable::default();
144        assert_eq!(default_table.get(&Color::Red), &"");
145        assert_eq!(default_table.get(&Color::Green), &"");
146        assert_eq!(default_table.get(&Color::Blue), &"");
147    }
148
149    #[test]
150    fn index_impl() {
151        assert_eq!(TABLES[Color::Red], "Red");
152        assert_eq!(TABLES[Color::Green], "Green");
153        assert_eq!(TABLES[Color::Blue], "Blue");
154
155        let mut mutable_table = TABLES;
156        mutable_table[Color::Red] = "Changed Red";
157        assert_eq!(mutable_table[Color::Red], "Changed Red");
158    }
159
160    #[test]
161    fn as_ref_impl() {
162        let slice: &[&str] = TABLES.as_ref();
163        assert_eq!(slice.len(), 3);
164    }
165
166    #[test]
167    fn as_mut_impl() {
168        let mut table = TABLES;
169        let slice: &mut [&str] = table.as_mut();
170        slice[0] = "Changed";
171        assert_eq!(table.as_slice()[0], "Changed");
172    }
173}