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}