firewood_storage/node/
children.rs1use crate::PathComponent;
5
6const MAX_CHILDREN: usize = PathComponent::LEN;
7
8pub type ChildrenSlots<T> = std::iter::Zip<
11 std::array::IntoIter<PathComponent, MAX_CHILDREN>,
12 std::array::IntoIter<T, MAX_CHILDREN>,
13>;
14
15pub type IterPresentRef<'a, T> = std::iter::FilterMap<
17 ChildrenSlots<&'a Option<T>>,
18 fn((PathComponent, &'a Option<T>)) -> Option<(PathComponent, &'a T)>,
19>;
20
21pub type IterPresentMut<'a, T> = std::iter::FilterMap<
23 ChildrenSlots<&'a mut Option<T>>,
24 fn((PathComponent, &'a mut Option<T>)) -> Option<(PathComponent, &'a mut T)>,
25>;
26
27#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct Children<T>([T; MAX_CHILDREN]);
30
31impl<T: std::fmt::Debug> std::fmt::Debug for Children<T> {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 f.debug_map()
34 .entries(self.iter().map(|(pc, child)| (pc.as_u8(), child)))
35 .finish()
36 }
37}
38
39impl<T> Children<T> {
40 #[must_use]
43 pub fn from_fn(f: impl FnMut(PathComponent) -> T) -> Self {
44 Self(PathComponent::ALL.map(f))
45 }
46
47 #[must_use]
49 pub const fn each_ref(&self) -> Children<&T> {
50 Children(self.0.each_ref())
51 }
52
53 #[must_use]
56 pub const fn each_mut(&mut self) -> Children<&mut T> {
57 Children(self.0.each_mut())
58 }
59
60 #[must_use]
64 pub const fn get(&self, index: PathComponent) -> &T {
65 #![expect(clippy::indexing_slicing)]
66 &self.0[index.as_usize()]
67 }
68
69 #[must_use]
73 pub const fn get_mut(&mut self, index: PathComponent) -> &mut T {
74 #![expect(clippy::indexing_slicing)]
75 &mut self.0[index.as_usize()]
76 }
77
78 pub const fn replace(&mut self, index: PathComponent, value: T) -> T {
83 #![expect(clippy::indexing_slicing)]
84 std::mem::replace(&mut self.0[index.as_usize()], value)
85 }
86
87 #[must_use]
90 pub fn map<O>(self, mut f: impl FnMut(PathComponent, T) -> O) -> Children<O> {
91 let mut pc = const { PathComponent::ALL[0] };
92 Children(self.0.map(|child| {
93 let out = f(pc, child);
94 pc = pc.wrapping_next();
95 out
96 }))
97 }
98
99 pub fn iter(&self) -> ChildrenSlots<&T> {
102 self.into_iter()
103 }
104
105 pub fn iter_mut(&mut self) -> ChildrenSlots<&mut T> {
108 self.into_iter()
109 }
110
111 pub fn merge<U, V, E>(
118 self,
119 other: Children<U>,
120 mut merge: impl FnMut(PathComponent, T, U) -> Result<Option<V>, E>,
121 ) -> Result<Children<Option<V>>, E> {
122 let iter = self.0.into_iter().zip(other.0);
123 let mut output = [const { None }; MAX_CHILDREN];
124 for (slot, (pc, (a, b))) in output
125 .iter_mut()
126 .zip(PathComponent::ALL.into_iter().zip(iter))
127 {
128 *slot = merge(pc, a, b)?;
129 }
130 Ok(Children(output))
131 }
132}
133
134impl<T> Children<Option<T>> {
135 #[must_use]
137 pub const fn new() -> Self {
138 Self([const { None }; MAX_CHILDREN])
139 }
140
141 #[must_use]
143 pub fn count(&self) -> usize {
144 self.0.iter().filter(|c| c.is_some()).count()
145 }
146
147 #[must_use]
149 pub const fn take(&mut self, index: PathComponent) -> Option<T> {
150 self.replace(index, None)
151 }
152
153 pub fn iter_present(&self) -> IterPresentRef<'_, T> {
156 self.into_iter()
157 .filter_map(|(pc, opt)| opt.as_ref().map(|v| (pc, v)))
158 }
159}
160
161impl<T> Default for Children<Option<T>> {
162 fn default() -> Self {
163 Self::new()
164 }
165}
166
167impl<'a, T> Children<&'a Option<T>> {
168 #[must_use]
170 pub fn count(&self) -> usize {
171 self.0.iter().filter(|c| c.is_some()).count()
172 }
173
174 pub fn iter_present(self) -> IterPresentRef<'a, T> {
177 self.into_iter()
178 .filter_map(|(pc, opt)| opt.as_ref().map(|v| (pc, v)))
179 }
180}
181
182impl<'a, T> Children<&'a mut Option<T>> {
183 #[must_use]
185 pub fn count(&self) -> usize {
186 self.0.iter().filter(|c| c.is_some()).count()
187 }
188
189 pub fn iter_present(self) -> IterPresentMut<'a, T> {
192 self.into_iter()
193 .filter_map(|(pc, opt)| opt.as_mut().map(|v| (pc, v)))
194 }
195}
196
197impl<T> std::ops::Index<PathComponent> for Children<T> {
198 type Output = T;
199
200 fn index(&self, index: PathComponent) -> &Self::Output {
201 self.get(index)
202 }
203}
204
205impl<T> std::ops::IndexMut<PathComponent> for Children<T> {
206 fn index_mut(&mut self, index: PathComponent) -> &mut Self::Output {
207 self.get_mut(index)
208 }
209}
210
211impl<T> IntoIterator for Children<T> {
212 type Item = (PathComponent, T);
213 type IntoIter = ChildrenSlots<T>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 PathComponent::ALL.into_iter().zip(self.0)
217 }
218}
219
220impl<'a, T: 'a> IntoIterator for &'a Children<T> {
221 type Item = (PathComponent, &'a T);
222 type IntoIter = ChildrenSlots<&'a T>;
223
224 fn into_iter(self) -> Self::IntoIter {
225 self.each_ref().into_iter()
226 }
227}
228
229impl<'a, T: 'a> IntoIterator for &'a mut Children<T> {
230 type Item = (PathComponent, &'a mut T);
231 type IntoIter = ChildrenSlots<&'a mut T>;
232
233 fn into_iter(self) -> Self::IntoIter {
234 self.each_mut().into_iter()
235 }
236}