bitstring_trees/tree/
path.rs1use bitstring::BitString as _;
2
3use super::{
4 goto::{
5 LookupStepWith,
6 NodeRef as _,
7 },
8 IterMutPath,
9 Node,
10 TreeProperties,
11};
12
13pub struct MutPath<'r, TP: TreeProperties> {
15 start: bool,
16 current: Option<&'r mut Node<TP>>,
17 target: TP::Key,
18 target_len: usize,
19}
20
21impl<'r, TP: TreeProperties> MutPath<'r, TP> {
22 pub(in crate::tree) fn new(root: Option<&'r mut Node<TP>>, key: TP::Key) -> Self {
23 Self {
24 start: true,
25 current: root,
26 target_len: key.len(),
27 target: key,
28 }
29 }
30
31 #[allow(clippy::should_implement_trait)] pub fn next(&mut self) -> Option<&mut Node<TP>> {
34 let lookup_step = if self.start {
35 self.start = false;
36 self.current
37 .take()?
38 .lookup_initial_step(&self.target, self.target_len)
39 } else {
40 self.current
41 .take()?
42 .lookup_step(&self.target, self.target_len)
43 };
44
45 match lookup_step {
46 LookupStepWith::Found(node, _) => Some(node),
47 LookupStepWith::Path(node, _) => {
48 self.current = Some(node);
49 Some(self.current.as_mut()?)
50 },
51 LookupStepWith::Miss => None,
52 }
53 }
54}
55
56impl<'r, TP: TreeProperties> IntoIterator for MutPath<'r, TP> {
57 type IntoIter = IterMutPath<'r, TP>;
58 type Item = (
59 &'r TP::Key,
60 &'r mut TP::Value,
61 Option<&'r mut TP::LeafValue>,
62 );
63
64 fn into_iter(self) -> Self::IntoIter {
65 IterMutPath::new(self)
66 }
67}
68
69pub struct IterPath<'r, TP: TreeProperties> {
71 start: bool,
72 current: Option<&'r Node<TP>>,
73 target: TP::Key,
74 target_len: usize,
75}
76
77impl<'r, TP: TreeProperties> IterPath<'r, TP> {
78 pub(in crate::tree) fn new(node: Option<&'r Node<TP>>, key: TP::Key) -> Self {
79 Self {
80 start: true,
81 current: node,
82 target_len: key.len(),
83 target: key,
84 }
85 }
86}
87
88impl<'r, TP: TreeProperties> Iterator for IterPath<'r, TP> {
89 type Item = &'r Node<TP>;
90
91 fn next(&mut self) -> Option<&'r Node<TP>> {
92 let current = self.current.take()?;
93 let lookup_step = if self.start {
94 self.start = false;
95 current.lookup_initial_step(&self.target, self.target_len)
96 } else {
97 current.lookup_step(&self.target, self.target_len)
98 };
99
100 match lookup_step {
101 LookupStepWith::Found(node, _) => Some(node),
102 LookupStepWith::Path(node, _) => {
103 self.current = Some(node);
104 Some(node)
105 },
106 LookupStepWith::Miss => None,
107 }
108 }
109}