Skip to content

Commit ff4b043

Browse files
committed
Add traverse functions for NodeMut
1 parent ecd16e5 commit ff4b043

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed

src/lib.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ impl<'a, T: 'a> NodeMut<'a, T> {
369369
&mut self.node().value
370370
}
371371

372+
/// Downcast `NodeMut` to `NodeRef`.
373+
pub fn as_ref(&mut self) -> NodeRef<'_, T> {
374+
unsafe { self.tree.get_unchecked(self.id) }
375+
}
376+
372377
fn axis<F>(&mut self, f: F) -> Option<NodeMut<T>>
373378
where
374379
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
@@ -463,6 +468,115 @@ impl<'a, T: 'a> NodeMut<'a, T> {
463468
unsafe { self.tree.get_unchecked(self.id).has_children() }
464469
}
465470

471+
/// Apply function for each ancestor mutable node reference.
472+
pub fn for_each_ancestor<F>(&mut self, mut f: F)
473+
where
474+
F: FnMut(&mut NodeMut<T>),
475+
{
476+
let mut current = self.parent();
477+
while let Some(mut node) = current {
478+
f(&mut node);
479+
current = node.into_parent().ok();
480+
}
481+
}
482+
483+
/// Apply function for each next sibling mutable node reference.
484+
pub fn for_each_next_sibling<F>(&mut self, mut f: F)
485+
where
486+
F: FnMut(&mut NodeMut<T>),
487+
{
488+
let mut current = self.next_sibling();
489+
while let Some(mut node) = current {
490+
f(&mut node);
491+
current = node.into_next_sibling().ok();
492+
}
493+
}
494+
495+
/// Apply function for each previout sibling mutable node reference.
496+
pub fn for_each_prev_sibling<F>(&mut self, mut f: F)
497+
where
498+
F: FnMut(&mut NodeMut<T>),
499+
{
500+
let mut current = self.prev_sibling();
501+
while let Some(mut node) = current {
502+
f(&mut node);
503+
current = node.into_prev_sibling().ok();
504+
}
505+
}
506+
507+
/// Apply function for this node and each sibling mutable node reference.
508+
pub fn for_each_sibling<F>(&mut self, mut f: F)
509+
where
510+
F: FnMut(&mut NodeMut<T>),
511+
{
512+
self.for_each_prev_sibling(&mut f);
513+
f(self);
514+
self.for_each_next_sibling(&mut f);
515+
}
516+
517+
/// Apply function for each children mutable node reference.
518+
pub fn for_each_child<F>(&mut self, f: F)
519+
where
520+
F: FnMut(&mut NodeMut<T>),
521+
{
522+
if let Some(mut first_child) = self.first_child() {
523+
first_child.for_each_sibling(f);
524+
}
525+
}
526+
527+
/// Apply function for this node and each descendant mutable node reference.
528+
pub fn for_each_descendant<F>(&mut self, mut f: F)
529+
where
530+
F: FnMut(&mut NodeMut<T>),
531+
{
532+
let id = self.id();
533+
534+
f(self);
535+
536+
// Start at our first child, if any.
537+
let Some(mut node) = self.first_child() else {
538+
return;
539+
};
540+
541+
loop {
542+
f(&mut node);
543+
544+
// Try to go deeper into its first child.
545+
match node.into_first_child() {
546+
Ok(child) => {
547+
node = child;
548+
continue;
549+
}
550+
Err(n) => {
551+
node = n;
552+
}
553+
}
554+
555+
// No deeper child, so climb until we find a next sibling or hit self.
556+
loop {
557+
match node.into_next_sibling() {
558+
Ok(sib) => {
559+
node = sib;
560+
break;
561+
}
562+
Err(n) => {
563+
node = n;
564+
}
565+
}
566+
567+
// No sibling, so climb up.
568+
if let Ok(parent) = node.into_parent() {
569+
if parent.id() == id {
570+
return;
571+
}
572+
node = parent;
573+
} else {
574+
unreachable!();
575+
}
576+
}
577+
}
578+
}
579+
466580
/// Appends a new child to this node.
467581
pub fn append(&mut self, value: T) -> NodeMut<T> {
468582
let id = self.tree.orphan(value).id;

tests/node_mut.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,77 @@ fn has_children() {
7474
assert!(!tree.root_mut().first_child().unwrap().has_children());
7575
}
7676

77+
#[test]
78+
fn for_each_next_sibling() {
79+
let mut tree = tree!(1 => { 2, 3, 4, 5, 6 });
80+
let mut root = tree.root_mut();
81+
let mut c = root.first_child().unwrap();
82+
83+
c.for_each_next_sibling(|n| {
84+
*n.value() += 1;
85+
});
86+
87+
let res = tree!(1 => { 2, 4, 5, 6, 7 });
88+
89+
assert_eq!(tree, res);
90+
}
91+
92+
#[test]
93+
fn for_each_prev_sibling() {
94+
let mut tree = tree!(1 => { 2, 3, 4, 5, 6 });
95+
let mut root = tree.root_mut();
96+
let mut c = root.last_child().unwrap();
97+
98+
c.for_each_prev_sibling(|n| {
99+
*n.value() += 1;
100+
});
101+
102+
let res = tree!(1 => { 3, 4, 5, 6, 6 });
103+
104+
assert_eq!(tree, res);
105+
}
106+
107+
#[test]
108+
fn for_each_sibling() {
109+
let rt = 2;
110+
let mut tree = tree!(rt => { 2, 3, 4, 5, 6 });
111+
let mut root = tree.root_mut();
112+
let mut c = root.last_child().unwrap();
113+
114+
c.for_each_sibling(|n| {
115+
let v = n.parent().map(|mut p| *p.value()).unwrap();
116+
*n.value() += v;
117+
});
118+
119+
let res = tree!(rt => { 4, 5, 6, 7, 8 });
120+
121+
assert_eq!(tree, res);
122+
}
123+
124+
#[test]
125+
fn for_each_child() {
126+
let mut tree = tree!(1 => { 2, 3, 4, 5, 6 });
127+
let mut root = tree.root_mut();
128+
root.for_each_child(|n| *n.value() += 1);
129+
130+
assert_eq!(*root.value(), 1);
131+
132+
let res = tree!(1 => { 3, 4, 5, 6, 7 });
133+
134+
assert_eq!(tree, res);
135+
}
136+
137+
#[test]
138+
fn for_each_descendant() {
139+
let mut tree = tree!(1 => { 2 => {3, 4, 5, 6}, 3, 4 => {0, 1}, 5, 6 => {1, 2} });
140+
let mut root = tree.root_mut();
141+
root.for_each_descendant(|n| *n.value() += 1);
142+
143+
let tree2 = tree!(2 => { 3 => {4, 5, 6, 7}, 4, 5 => {1, 2}, 6, 7 => {2, 3} });
144+
145+
assert_eq!(tree, tree2);
146+
}
147+
77148
#[test]
78149
fn append_1() {
79150
let mut tree = tree!('a');

0 commit comments

Comments
 (0)