1pub mod detached;
2pub mod node;
3
4use itertools::FoldWhile::{Continue, Done};
5use itertools::Itertools;
6
7use replace_with::{replace_with_or_abort, replace_with_or_abort_and_return};
9use std::hash::Hash;
10use std::ops::{Deref, DerefMut};
11
12use crate::path::Path;
13
14use self::detached::DetachedEntry;
15use self::node::Node;
16
17use super::iter::depth::Traversal;
18use super::{NodeIDX, Tree};
19
20pub(super) const TREEBOUND: bool = false;
21pub(super) const NODEBOUND: bool = true;
22
23pub enum Entry<R, N, B, const BOUND: bool>
24where
25 R: Deref<Target = Tree<N, B>>,
26{
27 Node(Node<R, N, B, BOUND>),
28 Detached(DetachedEntry<R, N, B, BOUND>),
29}
30
31pub type TreeRefEntry<'a, N, B, const BOUND: bool> = Entry<&'a Tree<N, B>, N, B, BOUND>;
32pub type TreeMutEntry<'a, N, B, const BOUND: bool> = Entry<&'a mut Tree<N, B>, N, B, BOUND>;
33
34impl<R, N, B, const BOUND: bool> From<Result<Node<R, N, B, BOUND>, DetachedEntry<R, N, B, BOUND>>>
35 for Entry<R, N, B, BOUND>
36where
37 R: Deref<Target = Tree<N, B>>,
38{
39 fn from(value: Result<Node<R, N, B, BOUND>, DetachedEntry<R, N, B, BOUND>>) -> Self {
40 match value {
41 Ok(n) => Entry::Node(n),
42 Err(d) => Entry::Detached(d),
43 }
44 }
45}
46
47impl<R, N, B, const BOUND: bool> From<Result<DetachedEntry<R, N, B, BOUND>, Node<R, N, B, BOUND>>>
48 for Entry<R, N, B, BOUND>
49where
50 R: Deref<Target = Tree<N, B>>,
51{
52 fn from(value: Result<DetachedEntry<R, N, B, BOUND>, Node<R, N, B, BOUND>>) -> Self {
53 match value {
54 Ok(d) => Entry::Detached(d),
55 Err(n) => Entry::Node(n),
56 }
57 }
58}
59
60impl<R, N, B, const BOUND: bool> From<Node<R, N, B, BOUND>> for Entry<R, N, B, BOUND>
61where
62 R: Deref<Target = Tree<N, B>>,
63{
64 fn from(value: Node<R, N, B, BOUND>) -> Self {
65 Entry::Node(value)
66 }
67}
68
69impl<R, N, B, const BOUND: bool> From<DetachedEntry<R, N, B, BOUND>> for Entry<R, N, B, BOUND>
70where
71 R: Deref<Target = Tree<N, B>>,
72{
73 fn from(value: DetachedEntry<R, N, B, BOUND>) -> Self {
74 Entry::Detached(value)
75 }
76}
77
78impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
79where
80 R: Deref<Target = Tree<N, B>>,
81{
82 pub fn node(&self) -> Option<&Node<R, N, B, BOUND>> {
83 match self {
84 Entry::Node(node) => Some(node),
85 Entry::Detached(_) => None,
86 }
87 }
88
89 pub fn detached(&self) -> Option<&DetachedEntry<R, N, B, BOUND>> {
90 match self {
91 Entry::Node(_) => None,
92 Entry::Detached(detached) => Some(detached),
93 }
94 }
95
96 pub fn node_mut(&mut self) -> Option<&mut Node<R, N, B, BOUND>> {
97 match self {
98 Entry::Node(node) => Some(node),
99 Entry::Detached(_) => None,
100 }
101 }
102
103 pub fn detached_mut(&mut self) -> Option<&mut DetachedEntry<R, N, B, BOUND>> {
104 match self {
105 Entry::Node(_) => None,
106 Entry::Detached(detached) => Some(detached),
107 }
108 }
109
110 pub fn is_node(&self) -> bool {
111 match self {
112 Entry::Node(_) => true,
113 Entry::Detached(_) => false,
114 }
115 }
116
117 pub fn is_detached(&self) -> bool {
118 !self.is_node()
119 }
120
121 pub fn branch(&self) -> Option<&B> {
122 match self {
123 Entry::Node(attached) => attached.branch(),
124 Entry::Detached(detached) => detached.branch(),
125 }
126 }
127
128 pub fn path(&self) -> &Path<B> {
129 match self {
130 Entry::Node(attached) => attached.path(),
131 Entry::Detached(detached) => detached.path(),
132 }
133 }
134
135 pub fn value(&self) -> Option<&N> {
136 match self {
137 Entry::Node(attached) => Some(attached.value()),
138 Entry::Detached(_) => None,
139 }
140 }
141}
142
143impl<R, N, B> Entry<R, N, B, TREEBOUND>
144where
145 R: Deref<Target = Tree<N, B>>,
146 B: Eq + Hash + Clone,
147{
148 pub fn apply_move<T>(&mut self, node: &Traversal<T, B>) -> Result<(), usize> {
152 if let Traversal::Step {
153 up,
154 branch,
155 data: _,
156 } = node
157 {
158 if self.path().len() < *up {
160 Err(*up - self.path().len())
161 } else {
162 assert!(self.move_up(*up).is_none());
163 self.move_down_branch(branch.clone());
164 Ok(())
165 }
166 } else {
167 Ok(())
168 }
169 }
193
194 pub fn apply_move_deref<T, C>(&mut self, node: &Traversal<T, C>) -> bool
196 where
197 C: Deref<Target = B>,
198 {
199 if let Traversal::Step {
200 up,
201 branch,
202 data: _,
203 } = node
204 {
205 self.move_up(*up);
206 self.move_down(path![(*branch).clone()]);
207 true
208 } else {
209 replace_with_or_abort_and_return(self, |s| {
210 if let Entry::Detached(detached) = s {
211 if detached.position.is_empty() {
213 (
214 true,
215 if detached.tree.get_root().is_some() {
216 let attached = detached.position.attach(0).unwrap_attached();
218 Node::from(detached.tree, attached).into()
219 } else {
220 detached.into()
221 },
222 )
223 } else {
224 (false, detached.into())
225 }
226 } else {
227 (false, s)
228 }
229 })
230 }
231 }
232}
233
234impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
235where
236 R: Deref<Target = Tree<N, B>>,
237 B: Eq + Hash,
238{
239 pub fn from(tree: R, root: NodeIDX, path: Path<B>) -> Self {
240 let mut detached = false;
241 let idxs = path
242 .iter()
243 .fold_while(Path::new(), |mut ph, b| {
244 ph.push_last(
245 if let Some(c_idx) = tree.nodes[*ph.last().unwrap_or(&root)].children.get(b) {
246 *c_idx
247 } else {
248 detached = true;
249 return Done(ph);
250 },
251 );
252 Continue(ph)
253 })
254 .into_inner();
255 if detached {
256 Self::Detached((tree, path, idxs).into())
257 } else {
258 Self::Node((tree, path, idxs).into())
259 }
260 }
261}
262
263impl<R, N, B> Entry<R, N, B, TREEBOUND>
264where
265 R: DerefMut<Target = Tree<N, B>>,
266 B: Eq + Hash + Clone,
267{
268 pub fn remove_subtree(self) -> Self {
269 match self {
270 Entry::Node(node) => node.remove_subtree().into(),
271 Entry::Detached(_) => self,
272 }
273 }
274}
275
276impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
277where
278 R: DerefMut<Target = Tree<N, B>>,
279 B: Eq + Hash + Clone,
280{
281 pub fn and_modify<F>(mut self, f: F) -> Self
282 where
283 F: FnOnce(&mut N),
284 {
285 if let Entry::Node(ref mut node) = self {
286 f(node.value_mut());
287 }
288 self
289 }
290 pub fn apply_data(&mut self, node: Traversal<N, B>) -> bool {
292 let mut r = true;
293 replace_with_or_abort(self, |s| match s {
294 Entry::Node(mut n) => {
295 n.insert(node.take());
296 n.into()
297 }
298 Entry::Detached(d) => d
299 .insert(node.take())
300 .map_err(|e| {
301 r = false;
302 e
303 })
304 .into(),
305 });
306 r
307 }
308}
309impl<R, N, B> Entry<R, N, B, TREEBOUND>
310where
311 R: DerefMut<Target = Tree<N, B>>,
312 B: Eq + Hash + Clone,
313{
314 pub fn apply(&mut self, node: Traversal<N, B>) -> bool {
315 self.apply_move(&node).is_ok() && self.apply_data(node)
316 }
317}
318
319impl<R, N, B> Entry<R, N, B, TREEBOUND>
320where
321 R: DerefMut<Target = Tree<N, B>>,
322 N: Clone + Default,
323 B: Eq + Hash + Clone + Default,
324{
325 pub fn apply_extend(&mut self, node: Traversal<N, B>) -> bool {
326 if let Traversal::Start(value) = node {
327 return replace_with_or_abort_and_return(self, |s| {
328 if let Entry::Detached(detached) = s {
329 if !detached.position.is_rooted() {
330 (true, detached.insert(value.clone()).into())
331 } else {
332 (false, detached.into())
333 }
334 } else {
335 (false, s)
336 }
337 });
338 }
339 self.move_up(node.up());
340 self.move_down(path![node.branch().unwrap().clone()]);
341 let r = true;
343 replace_with_or_abort(self, |s| match s {
344 Entry::Node(mut n) => {
345 n.insert(node.take());
346 n.into()
347 }
348 Entry::Detached(d) => d.insert_extend(node.take()).into(),
349 });
350
351 r
352 }
353}
354
355impl<R, N, B> Entry<R, N, B, TREEBOUND>
356where
357 R: Deref<Target = Tree<N, B>>,
358 B: Eq + Hash + Clone,
359{
360 pub fn move_down(&mut self, path: Path<B>) {
361 replace_with_or_abort(self, |s| match s {
362 Entry::Node(node) => node.move_down(path),
363 Entry::Detached(mut detached) => {
364 detached.move_down(path);
365 detached.into_entry()
366 }
367 })
368 }
369 pub fn move_down_branch(&mut self, branch: B) {
370 replace_with_or_abort(self, |s| match s {
371 Entry::Node(node) => node.move_down_branch(branch),
372 Entry::Detached(mut detached) => {
373 detached.move_down_branch(branch);
374 Entry::Detached(detached)
375 }
376 })
377 }
378 pub fn move_up(&mut self, up: usize) -> Option<usize> {
379 let mut overflow = None;
380 replace_with_or_abort(self, |s| match s {
381 Entry::Node(mut node) => {
382 overflow = node.move_up(up);
383 node.into_entry()
384 }
385 Entry::Detached(detached) => {
386 let (e, o) = detached.move_up(up);
387 overflow = o;
388 e
389 }
390 });
391 overflow
392 }
393 pub fn move_to_attached(&mut self) {
394 replace_with_or_abort(self, |s| {
395 if let Entry::Detached(detached) = s {
396 detached.move_to_attached().into()
397 } else {
398 s
399 }
400 });
401 }
402}
403
404impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
405where
406 R: Deref<Target = Tree<N, B>>,
407 B: Eq + Hash + Clone,
408{
409 pub fn offshoot_len(&self) -> usize {
410 match self {
411 Entry::Node(_) => 0,
412 Entry::Detached(detached) => detached.offshoot_len(),
413 }
414 }
415}
416impl<R, N, B, const BOUND: bool> Entry<R, N, B, BOUND>
417where
418 R: DerefMut<Target = Tree<N, B>>,
419 B: Eq + Hash + Clone,
420{
421 pub fn or_insert(&mut self, value: N) -> &mut N {
422 if self.is_detached() {
423 replace_with_or_abort(self, |s| {
430 if let Entry::Detached(detached) = s {
431 detached.insert(value).into()
432 } else {
433 s
434 }
435 });
436 }
437 let idx = *self.node().unwrap().position.at();
438 &mut self.node_mut().unwrap().tree.nodes[idx].value
440 }
441
442 pub fn insert(&mut self, value: N) -> Option<&mut N> {
443 replace_with_or_abort(self, |s| match s {
444 Entry::Detached(detached_entry) => {
446 detached_entry.insert(value).into()
451 }
452 Entry::Node(mut node) => {
453 node.insert(value);
454 node.into_entry()
455 }
456 });
457
458 let idx = *self.node().unwrap().position.at();
459 self.node_mut().map(|node| &mut node.tree.nodes[idx].value)
460 }
461}
462
463impl<R, N, B> Entry<R, N, B, TREEBOUND>
464where
465 R: DerefMut<Target = Tree<N, B>>,
466 N: Default,
467 B: Default + Eq + Hash + Clone,
468{
469 pub fn or_insert_extend(&mut self, value: N) -> &mut N {
470 replace_with_or_abort(self, |s| {
471 if let Entry::Detached(detached_entry) = s {
472 detached_entry.insert_extend(value).into()
473 } else {
474 s
475 }
476 });
477 let idx = *self.node().unwrap().position.at();
478 &mut self.node_mut().unwrap().tree.nodes[idx].value
479 }
480
481 pub fn insert_extend(&mut self, value: N) -> &mut N {
482 replace_with_or_abort(self, |s| match s {
483 Entry::Detached(detached_entry) => detached_entry.insert_extend(value).into(),
484 Entry::Node(mut node) => {
485 node.insert(value);
486 node.into()
487 }
488 });
489 let idx = *self.node().unwrap().position.at();
490 &mut self.node_mut().unwrap().tree.nodes[idx].value
491 }
492}