1use core::marker::PhantomData;
2
3use crate::{IntoKeys, KeyLookup, Keys, Metadata, Node, Transcode, Traversal, TreeKey};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct ExactSize<T> {
8 iter: T,
9 count: usize,
10}
11
12impl<T: Iterator> Iterator for ExactSize<T> {
13 type Item = T::Item;
14
15 #[inline]
16 fn next(&mut self) -> Option<Self::Item> {
17 if let Some(v) = self.iter.next() {
18 self.count -= 1; Some(v)
20 } else {
21 debug_assert!(self.count == 0);
22 None
23 }
24 }
25
26 #[inline]
27 fn size_hint(&self) -> (usize, Option<usize>) {
28 (self.count, Some(self.count))
29 }
30}
31
32impl<T> ExactSize<T> {
33 #[inline]
35 pub fn inner(&self) -> &T {
36 &self.iter
37 }
38}
39
40impl<T: Iterator> ExactSizeIterator for ExactSize<T> {}
43
44impl<T: Iterator> core::iter::FusedIterator for ExactSize<T> {}
46
47pub(crate) struct Consume<T>(pub(crate) T);
52impl<T: Keys> Keys for Consume<T> {
53 #[inline]
54 fn next(&mut self, lookup: &KeyLookup) -> Result<usize, Traversal> {
55 self.0.next(lookup)
56 }
57
58 #[inline]
59 fn finalize(&mut self) -> Result<(), Traversal> {
60 Ok(())
61 }
62}
63
64impl<T: Keys> IntoKeys for Consume<T> {
65 type IntoKeys = Self;
66
67 #[inline]
68 fn into_keys(self) -> Self::IntoKeys {
69 self
70 }
71}
72
73#[derive(Clone, Debug, PartialEq, Eq)]
83pub struct NodeIter<M: ?Sized, N, const D: usize> {
84 state: [usize; D],
88 root: usize,
89 depth: usize,
90 _n: PhantomData<N>,
91 _m: PhantomData<M>,
92}
93
94impl<M: ?Sized, N, const D: usize> Default for NodeIter<M, N, D> {
95 fn default() -> Self {
96 Self {
97 state: [0; D],
98 root: 0,
99 depth: D + 1,
101 _n: PhantomData,
102 _m: PhantomData,
103 }
104 }
105}
106
107impl<M: TreeKey + ?Sized, N, const D: usize> NodeIter<M, N, D> {
108 pub fn root<K: IntoKeys>(mut self, root: K) -> Result<Self, Traversal> {
112 let node = self.state.transcode::<M, _>(root)?;
113 self.root = node.depth();
114 self.depth = D + 1;
115 Ok(self)
116 }
117
118 pub fn exact_size(self) -> ExactSize<Self> {
125 assert_eq!(self.depth, D + 1, "NodeIter partially consumed");
126 assert_eq!(self.root, 0, "NodeIter on sub-tree");
127 debug_assert_eq!(&self.state, &[0; D]); let meta: Metadata = M::traverse_all();
129 assert!(
130 D >= meta.max_depth,
131 "depth D = {D} must be at least {}",
132 meta.max_depth
133 );
134 ExactSize {
135 iter: self,
136 count: meta.count.get(),
137 }
138 }
139
140 pub fn current_depth(&self) -> usize {
142 self.depth
143 }
144
145 pub fn root_depth(&self) -> usize {
147 self.root
148 }
149}
150
151impl<M, N, const D: usize> Iterator for NodeIter<M, N, D>
152where
153 M: TreeKey + ?Sized,
154 N: Transcode + Default,
155{
156 type Item = Result<(N, Node), usize>;
157
158 fn next(&mut self) -> Option<Self::Item> {
159 loop {
160 debug_assert!(self.depth >= self.root);
161 debug_assert!(self.depth <= D + 1);
162 if self.depth == self.root {
163 return None;
165 }
166 if self.depth <= D {
167 self.state[self.depth - 1] += 1;
169 }
170 return match M::transcode(Consume(self.state.iter().into_keys())) {
171 Err(Traversal::NotFound(depth)) => {
172 self.state[depth - 1] = 0;
175 self.depth = (depth - 1).max(self.root);
176 continue;
177 }
178 Ok((path, node)) => {
179 self.depth = node.depth();
181 Some(Ok((path, node)))
182 }
183 Err(Traversal::TooShort(depth)) => {
184 Some(Err(depth))
186 }
187 _ => unreachable!(),
190 };
191 }
192 }
193}
194
195impl<M: TreeKey + ?Sized, N: Transcode + Default, const D: usize> core::iter::FusedIterator
197 for NodeIter<M, N, D>
198{
199}