bitstring_trees/
walk_mut.rs1use core::{
4 marker::PhantomData,
5 ptr::NonNull,
6};
7
8use alloc::vec::Vec;
9
10pub enum NodeOrTree<T, N> {
12 Node(N),
14 Tree(T),
16}
17
18impl<T, N> NodeOrTree<T, N> {
19 pub fn map_tree<F, U>(self, f: F) -> NodeOrTree<U, N>
21 where
22 F: FnOnce(T) -> U,
23 {
24 match self {
25 Self::Tree(r) => NodeOrTree::Tree(f(r)),
26 Self::Node(n) => NodeOrTree::Node(n),
27 }
28 }
29
30 pub fn map_node<F, U>(self, f: F) -> NodeOrTree<T, U>
32 where
33 F: FnOnce(N) -> U,
34 {
35 match self {
36 Self::Tree(r) => NodeOrTree::Tree(r),
37 Self::Node(n) => NodeOrTree::Node(f(n)),
38 }
39 }
40
41 pub fn node(self) -> Option<N> {
43 match self {
44 Self::Tree(_) => None,
45 Self::Node(n) => Some(n),
46 }
47 }
48}
49
50impl<N> NodeOrTree<N, N> {
51 #[inline]
53 pub fn flatten(self) -> N {
54 match self {
55 Self::Tree(r) => r,
56 Self::Node(n) => n,
57 }
58 }
59}
60
61impl<N> NodeOrTree<Option<N>, N> {
62 #[inline]
64 pub fn flatten_optional(self) -> Option<N> {
65 match self {
66 Self::Tree(r) => r,
67 Self::Node(n) => Some(n),
68 }
69 }
70}
71
72pub struct WalkMut<'r, T: ?Sized, N: ?Sized, A = ()> {
86 _lifetime: PhantomData<&'r mut T>,
87 tree: NonNull<T>,
88 stack: Vec<(NonNull<N>, A)>,
89}
90
91impl<'r, T: ?Sized, N: ?Sized, A> WalkMut<'r, T, N, A> {
92 pub fn new(tree: &'r mut T) -> Self {
94 Self {
95 _lifetime: PhantomData,
96 tree: tree.into(),
97 stack: Vec::new(),
98 }
99 }
100
101 pub fn try_walk<F, E>(&mut self, with: F) -> Result<(), E>
105 where
106 F: for<'n> FnOnce(NodeOrTree<&'n mut T, &'n mut N>) -> Result<(&'n mut N, A), E>,
107 {
108 match with(self.current_mut()) {
109 Err(e) => Err(e),
110 Ok((next, add)) => {
111 let next: NonNull<N> = next.into();
112 self.stack.push((next, add));
113 Ok(())
114 },
115 }
116 }
117
118 pub fn pop(&mut self) -> Option<A> {
123 Some(self.stack.pop()?.1)
124 }
125
126 pub fn pop_all(&mut self) -> &mut T {
128 self.stack.clear();
129 unsafe { self.tree.as_mut() }
130 }
131
132 pub fn current_mut(&mut self) -> NodeOrTree<&mut T, &mut N> {
138 if let Some((cur, _)) = self.stack.last_mut() {
139 NodeOrTree::Node(unsafe { cur.as_mut() })
140 } else {
141 NodeOrTree::Tree(unsafe { self.tree.as_mut() })
142 }
143 }
144
145 pub fn into_current_mut(mut self) -> NodeOrTree<&'r mut T, &'r mut N> {
151 if let Some((cur, _)) = self.stack.last_mut() {
154 NodeOrTree::Node(unsafe { cur.as_mut() })
155 } else {
156 NodeOrTree::Tree(unsafe { self.tree.as_mut() })
157 }
158 }
159
160 pub fn into_tree_mut(mut self) -> &'r mut T {
162 self.stack.clear();
163 unsafe { self.tree.as_mut() }
165 }
166
167 pub fn current(&self) -> NodeOrTree<&T, &N> {
169 if let Some((cur, _)) = self.stack.last() {
170 NodeOrTree::Node(unsafe { cur.as_ref() })
171 } else {
172 NodeOrTree::Tree(unsafe { self.tree.as_ref() })
173 }
174 }
175}