1use crate::{EnumTable, Enumable};
2
3impl<K: Enumable, V, const N: usize> EnumTable<K, V, N> {
4 pub fn keys(&self) -> core::slice::Iter<'_, K> {
6 K::VARIANTS.iter()
7 }
8
9 pub fn values(&self) -> core::slice::Iter<'_, V> {
11 self.table.iter()
12 }
13
14 pub fn values_mut(&mut self) -> core::slice::IterMut<'_, V> {
16 self.table.iter_mut()
17 }
18
19 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
21 self.into_iter()
22 }
23
24 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
26 self.into_iter()
27 }
28}
29
30impl<K: Enumable, V, const N: usize> IntoIterator for EnumTable<K, V, N> {
31 type Item = (K, V);
32 type IntoIter = core::iter::Map<
33 core::iter::Enumerate<core::array::IntoIter<V, N>>,
34 fn((usize, V)) -> (K, V),
35 >;
36
37 fn into_iter(self) -> Self::IntoIter {
38 self.table
39 .into_iter()
40 .enumerate()
41 .map(|(i, v)| (K::VARIANTS[i], v))
42 }
43}
44
45impl<'a, K: Enumable, V, const N: usize> IntoIterator for &'a EnumTable<K, V, N> {
46 type Item = (&'a K, &'a V);
47 type IntoIter = core::iter::Map<
48 core::iter::Enumerate<core::slice::Iter<'a, V>>,
49 fn((usize, &'a V)) -> (&'a K, &'a V),
50 >;
51
52 fn into_iter(self) -> Self::IntoIter {
53 self.table
54 .iter()
55 .enumerate()
56 .map(|(i, v)| (&K::VARIANTS[i], v))
57 }
58}
59
60impl<K: Enumable, V, const N: usize> Extend<(K, V)> for EnumTable<K, V, N> {
61 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
62 for (k, v) in iter {
63 self.set(&k, v);
64 }
65 }
66}
67
68impl<'a, K: Enumable, V: Copy, const N: usize> Extend<(&'a K, &'a V)> for EnumTable<K, V, N> {
69 fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
70 for (k, v) in iter {
71 self.set(k, *v);
72 }
73 }
74}
75
76impl<'a, K: Enumable, V, const N: usize> IntoIterator for &'a mut EnumTable<K, V, N> {
77 type Item = (&'a K, &'a mut V);
78 type IntoIter = core::iter::Map<
79 core::iter::Enumerate<core::slice::IterMut<'a, V>>,
80 fn((usize, &'a mut V)) -> (&'a K, &'a mut V),
81 >;
82
83 fn into_iter(self) -> Self::IntoIter {
84 self.table
85 .iter_mut()
86 .enumerate()
87 .map(|(i, v)| (&K::VARIANTS[i], v))
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Enumable)]
96 enum Color {
97 Red,
98 Green,
99 Blue,
100 }
101
102 const TABLES: EnumTable<Color, &'static str, { Color::COUNT }> =
103 crate::et!(Color, &'static str, |color| match color {
104 Color::Red => "Red",
105 Color::Green => "Green",
106 Color::Blue => "Blue",
107 });
108
109 #[test]
110 fn into_iter_impl() {
111 let mut iter = TABLES.into_iter();
112 assert_eq!(iter.next(), Some((Color::Red, "Red")));
113 assert_eq!(iter.next(), Some((Color::Green, "Green")));
114 assert_eq!(iter.next(), Some((Color::Blue, "Blue")));
115 assert_eq!(iter.next(), None);
116 }
117
118 #[test]
119 fn into_iter_ref_impl() {
120 let mut iter = (&TABLES).into_iter();
121 assert_eq!(iter.next(), Some((&Color::Red, &"Red")));
122 assert_eq!(iter.next(), Some((&Color::Green, &"Green")));
123 assert_eq!(iter.next(), Some((&Color::Blue, &"Blue")));
124 assert_eq!(iter.next(), None);
125 }
126
127 #[test]
128 fn into_iter_mut_impl() {
129 let mut mutable_table = TABLES;
130 let mut iter = (&mut mutable_table).into_iter();
131 assert_eq!(iter.next(), Some((&Color::Red, &mut "Red")));
132 assert_eq!(iter.next(), Some((&Color::Green, &mut "Green")));
133 let blue = iter.next().unwrap();
134 assert_eq!(blue, (&Color::Blue, &mut "Blue"));
135 assert_eq!(iter.next(), None);
136
137 *blue.1 = "Modified Blue";
139 assert_eq!(mutable_table[Color::Blue], "Modified Blue");
140 }
141
142 #[test]
143 fn extend_owned() {
144 let mut table = TABLES;
145 table.extend([(Color::Red, "New Red"), (Color::Blue, "New Blue")]);
146 assert_eq!(table.get(&Color::Red), &"New Red");
147 assert_eq!(table.get(&Color::Green), &"Green");
148 assert_eq!(table.get(&Color::Blue), &"New Blue");
149 }
150
151 #[test]
152 fn extend_ref() {
153 let mut table = TABLES;
154 table.extend([(&Color::Red, &"New Red")]);
155 assert_eq!(table.get(&Color::Red), &"New Red");
156 assert_eq!(table.get(&Color::Green), &"Green");
157 }
158}