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}