Skip to content

Commit 6d36d3f

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

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

src/lib.rs

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