Skip to content

Commit 40859c1

Browse files
authored
Fix reparent methods to update parent for all siblings (#47)
Previously only first and last siblings had their parent updated, leaving middle siblings with stale parent references.
1 parent 2a90702 commit 40859c1

File tree

3 files changed

+107
-33
lines changed

3 files changed

+107
-33
lines changed

src/iter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,17 @@ impl<T> IntoIterator for Tree<T> {
114114

115115
impl<T> Tree<T> {
116116
/// Returns an iterator over values in insert order.
117-
pub fn values(&self) -> Values<T> {
117+
pub fn values(&self) -> Values<'_, T> {
118118
Values(self.vec.iter())
119119
}
120120

121121
/// Returns a mutable iterator over values in insert order.
122-
pub fn values_mut(&mut self) -> ValuesMut<T> {
122+
pub fn values_mut(&mut self) -> ValuesMut<'_, T> {
123123
ValuesMut(self.vec.iter_mut())
124124
}
125125

126126
/// Returns an iterator over nodes in insert order.
127-
pub fn nodes(&self) -> Nodes<T> {
127+
pub fn nodes(&self) -> Nodes<'_, T> {
128128
Nodes {
129129
tree: self,
130130
iter: 0..self.vec.len(),

src/lib.rs

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl<T> Tree<T> {
178178
}
179179

180180
/// Returns a reference to the specified node.
181-
pub fn get(&self, id: NodeId) -> Option<NodeRef<T>> {
181+
pub fn get(&self, id: NodeId) -> Option<NodeRef<'_, T>> {
182182
self.vec.get(id.to_index()).map(|node| NodeRef {
183183
id,
184184
node,
@@ -187,7 +187,7 @@ impl<T> Tree<T> {
187187
}
188188

189189
/// Returns a mutator of the specified node.
190-
pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<T>> {
190+
pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, T>> {
191191
let exists = self.vec.get(id.to_index()).map(|_| ());
192192
exists.map(move |_| NodeMut { id, tree: self })
193193
}
@@ -203,7 +203,7 @@ impl<T> Tree<T> {
203203
/// Returns a reference to the specified node.
204204
/// # Safety
205205
/// The caller must ensure that `id` is a valid node ID.
206-
pub unsafe fn get_unchecked(&self, id: NodeId) -> NodeRef<T> {
206+
pub unsafe fn get_unchecked(&self, id: NodeId) -> NodeRef<'_, T> {
207207
NodeRef {
208208
id,
209209
node: self.node(id),
@@ -214,22 +214,22 @@ impl<T> Tree<T> {
214214
/// Returns a mutator of the specified node.
215215
/// # Safety
216216
/// The caller must ensure that `id` is a valid node ID.
217-
pub unsafe fn get_unchecked_mut(&mut self, id: NodeId) -> NodeMut<T> {
217+
pub unsafe fn get_unchecked_mut(&mut self, id: NodeId) -> NodeMut<'_, T> {
218218
NodeMut { id, tree: self }
219219
}
220220

221221
/// Returns a reference to the root node.
222-
pub fn root(&self) -> NodeRef<T> {
222+
pub fn root(&self) -> NodeRef<'_, T> {
223223
unsafe { self.get_unchecked(NodeId::from_index(0)) }
224224
}
225225

226226
/// Returns a mutator of the root node.
227-
pub fn root_mut(&mut self) -> NodeMut<T> {
227+
pub fn root_mut(&mut self) -> NodeMut<'_, T> {
228228
unsafe { self.get_unchecked_mut(NodeId::from_index(0)) }
229229
}
230230

231231
/// Creates an orphan node.
232-
pub fn orphan(&mut self, value: T) -> NodeMut<T> {
232+
pub fn orphan(&mut self, value: T) -> NodeMut<'_, T> {
233233
let id = unsafe { NodeId::from_index(self.vec.len()) };
234234
self.vec.push(Node::new(value));
235235
unsafe { self.get_unchecked_mut(id) }
@@ -238,7 +238,7 @@ impl<T> Tree<T> {
238238
/// Merge with another tree as orphan, returning the new root of tree being merged.
239239
// Allowing this for compactness.
240240
#[allow(clippy::option_map_unit_fn)]
241-
pub fn extend_tree(&mut self, mut other_tree: Tree<T>) -> NodeMut<T> {
241+
pub fn extend_tree(&mut self, mut other_tree: Tree<T>) -> NodeMut<'_, T> {
242242
let offset = self.vec.len();
243243
let offset_id = |id: NodeId| -> NodeId {
244244
let old_index = id.to_index();
@@ -374,7 +374,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
374374
unsafe { self.tree.get_unchecked(self.id) }
375375
}
376376

377-
fn axis<F>(&mut self, f: F) -> Option<NodeMut<T>>
377+
fn axis<F>(&mut self, f: F) -> Option<NodeMut<'_, T>>
378378
where
379379
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
380380
{
@@ -394,7 +394,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
394394
}
395395

396396
/// Returns the parent of this node.
397-
pub fn parent(&mut self) -> Option<NodeMut<T>> {
397+
pub fn parent(&mut self) -> Option<NodeMut<'_, T>> {
398398
self.axis(|node| node.parent)
399399
}
400400

@@ -407,7 +407,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
407407
}
408408

409409
/// Returns the previous sibling of this node.
410-
pub fn prev_sibling(&mut self) -> Option<NodeMut<T>> {
410+
pub fn prev_sibling(&mut self) -> Option<NodeMut<'_, T>> {
411411
self.axis(|node| node.prev_sibling)
412412
}
413413

@@ -420,7 +420,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
420420
}
421421

422422
/// Returns the next sibling of this node.
423-
pub fn next_sibling(&mut self) -> Option<NodeMut<T>> {
423+
pub fn next_sibling(&mut self) -> Option<NodeMut<'_, T>> {
424424
self.axis(|node| node.next_sibling)
425425
}
426426

@@ -433,7 +433,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
433433
}
434434

435435
/// Returns the first child of this node.
436-
pub fn first_child(&mut self) -> Option<NodeMut<T>> {
436+
pub fn first_child(&mut self) -> Option<NodeMut<'_, T>> {
437437
self.axis(|node| node.children.map(|(id, _)| id))
438438
}
439439

@@ -446,7 +446,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
446446
}
447447

448448
/// Returns the last child of this node.
449-
pub fn last_child(&mut self) -> Option<NodeMut<T>> {
449+
pub fn last_child(&mut self) -> Option<NodeMut<'_, T>> {
450450
self.axis(|node| node.children.map(|(_, id)| id))
451451
}
452452

@@ -579,25 +579,25 @@ impl<'a, T: 'a> NodeMut<'a, T> {
579579
}
580580

581581
/// Appends a new child to this node.
582-
pub fn append(&mut self, value: T) -> NodeMut<T> {
582+
pub fn append(&mut self, value: T) -> NodeMut<'_, T> {
583583
let id = self.tree.orphan(value).id;
584584
self.append_id(id)
585585
}
586586

587587
/// Prepends a new child to this node.
588-
pub fn prepend(&mut self, value: T) -> NodeMut<T> {
588+
pub fn prepend(&mut self, value: T) -> NodeMut<'_, T> {
589589
let id = self.tree.orphan(value).id;
590590
self.prepend_id(id)
591591
}
592592

593593
/// Appends a subtree, return the root of the merged subtree.
594-
pub fn append_subtree(&mut self, subtree: Tree<T>) -> NodeMut<T> {
594+
pub fn append_subtree(&mut self, subtree: Tree<T>) -> NodeMut<'_, T> {
595595
let root_id = self.tree.extend_tree(subtree).id;
596596
self.append_id(root_id)
597597
}
598598

599599
/// Prepends a subtree, return the root of the merged subtree.
600-
pub fn prepend_subtree(&mut self, subtree: Tree<T>) -> NodeMut<T> {
600+
pub fn prepend_subtree(&mut self, subtree: Tree<T>) -> NodeMut<'_, T> {
601601
let root_id = self.tree.extend_tree(subtree).id;
602602
self.prepend_id(root_id)
603603
}
@@ -607,7 +607,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
607607
/// # Panics
608608
///
609609
/// Panics if this node is an orphan.
610-
pub fn insert_before(&mut self, value: T) -> NodeMut<T> {
610+
pub fn insert_before(&mut self, value: T) -> NodeMut<'_, T> {
611611
let id = self.tree.orphan(value).id;
612612
self.insert_id_before(id)
613613
}
@@ -617,7 +617,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
617617
/// # Panics
618618
///
619619
/// Panics if this node is an orphan.
620-
pub fn insert_after(&mut self, value: T) -> NodeMut<T> {
620+
pub fn insert_after(&mut self, value: T) -> NodeMut<'_, T> {
621621
let id = self.tree.orphan(value).id;
622622
self.insert_id_after(id)
623623
}
@@ -664,7 +664,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
664664
/// # Panics
665665
///
666666
/// Panics if `new_child_id` is not valid.
667-
pub fn append_id(&mut self, new_child_id: NodeId) -> NodeMut<T> {
667+
pub fn append_id(&mut self, new_child_id: NodeId) -> NodeMut<'_, T> {
668668
assert_ne!(
669669
self.id(),
670670
new_child_id,
@@ -703,7 +703,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
703703
/// # Panics
704704
///
705705
/// Panics if `new_child_id` is not valid.
706-
pub fn prepend_id(&mut self, new_child_id: NodeId) -> NodeMut<T> {
706+
pub fn prepend_id(&mut self, new_child_id: NodeId) -> NodeMut<'_, T> {
707707
assert_ne!(
708708
self.id(),
709709
new_child_id,
@@ -743,7 +743,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
743743
///
744744
/// - Panics if `new_sibling_id` is not valid.
745745
/// - Panics if this node is an orphan.
746-
pub fn insert_id_before(&mut self, new_sibling_id: NodeId) -> NodeMut<T> {
746+
pub fn insert_id_before(&mut self, new_sibling_id: NodeId) -> NodeMut<'_, T> {
747747
assert_ne!(
748748
self.id(),
749749
new_sibling_id,
@@ -786,7 +786,7 @@ impl<'a, T: 'a> NodeMut<'a, T> {
786786
///
787787
/// - Panics if `new_sibling_id` is not valid.
788788
/// - Panics if this node is an orphan.
789-
pub fn insert_id_after(&mut self, new_sibling_id: NodeId) -> NodeMut<T> {
789+
pub fn insert_id_after(&mut self, new_sibling_id: NodeId) -> NodeMut<'_, T> {
790790
assert_ne!(
791791
self.id(),
792792
new_sibling_id,
@@ -843,9 +843,14 @@ impl<'a, T: 'a> NodeMut<'a, T> {
843843
}
844844
};
845845

846-
unsafe {
847-
self.tree.node_mut(new_child_ids.0).parent = Some(self.id);
848-
self.tree.node_mut(new_child_ids.1).parent = Some(self.id);
846+
let mut child_id = new_child_ids.0;
847+
loop {
848+
let child = unsafe { self.tree.node_mut(child_id) };
849+
child.parent = Some(self.id);
850+
child_id = match child.next_sibling {
851+
Some(id) => id,
852+
None => break,
853+
};
849854
}
850855

851856
if self.node().children.is_none() {
@@ -882,9 +887,14 @@ impl<'a, T: 'a> NodeMut<'a, T> {
882887
}
883888
};
884889

885-
unsafe {
886-
self.tree.node_mut(new_child_ids.0).parent = Some(self.id);
887-
self.tree.node_mut(new_child_ids.1).parent = Some(self.id);
890+
let mut child_id = new_child_ids.0;
891+
loop {
892+
let child = unsafe { self.tree.node_mut(child_id) };
893+
child.parent = Some(self.id);
894+
child_id = match child.next_sibling {
895+
Some(id) => id,
896+
None => break,
897+
};
888898
}
889899

890900
if self.node().children.is_none() {

tests/node_mut.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,70 @@ fn reparent_from_id_prepend() {
492492
assert_eq!(Some(d), f.prev_sibling());
493493
}
494494

495+
#[test]
496+
fn reparent_from_id_append_multiple_siblings() {
497+
// Test reparenting when source has 3+ children to ensure all siblings get proper parent update
498+
let mut tree = tree! {
499+
'a' => {
500+
'b' => { 'x' }, // destination node
501+
'c' => { 'd', 'e', 'f' }, // source node with 3 children
502+
}
503+
};
504+
505+
let c_id = tree.root().last_child().unwrap().id();
506+
let b_id = tree.root().first_child().unwrap().id();
507+
508+
// Reparent children from 'c' to 'b'
509+
tree.root_mut()
510+
.first_child()
511+
.unwrap()
512+
.reparent_from_id_append(c_id);
513+
514+
let b = tree.get(b_id).unwrap();
515+
let x = b.first_child().unwrap(); // original child of b
516+
let d = x.next_sibling().unwrap(); // first reparented child
517+
let e = d.next_sibling().unwrap(); // middle reparented child
518+
let f = e.next_sibling().unwrap(); // last reparented child
519+
520+
// All children should now have 'b' as their parent
521+
assert_eq!(Some(b), x.parent());
522+
assert_eq!(Some(b), d.parent());
523+
assert_eq!(Some(b), e.parent());
524+
assert_eq!(Some(b), f.parent());
525+
}
526+
527+
#[test]
528+
fn reparent_from_id_prepend_multiple_siblings() {
529+
// Test reparenting when source has 3+ children to ensure all siblings get proper parent update
530+
let mut tree = tree! {
531+
'a' => {
532+
'b' => { 'x' }, // destination node
533+
'c' => { 'd', 'e', 'f' }, // source node with 3 children
534+
}
535+
};
536+
537+
let c_id = tree.root().last_child().unwrap().id();
538+
let b_id = tree.root().first_child().unwrap().id();
539+
540+
// Reparent children from 'c' to 'b'
541+
tree.root_mut()
542+
.first_child()
543+
.unwrap()
544+
.reparent_from_id_prepend(c_id);
545+
546+
let b = tree.get(b_id).unwrap();
547+
let d = b.first_child().unwrap(); // first reparented child
548+
let e = d.next_sibling().unwrap(); // middle reparented child
549+
let f = e.next_sibling().unwrap(); // last reparented child
550+
let x = f.next_sibling().unwrap(); // original child of b
551+
552+
// All children should now have 'b' as their parent
553+
assert_eq!(Some(b), d.parent());
554+
assert_eq!(Some(b), e.parent());
555+
assert_eq!(Some(b), f.parent());
556+
assert_eq!(Some(b), x.parent());
557+
}
558+
495559
#[test]
496560
fn into() {
497561
let mut tree = tree!('a');

0 commit comments

Comments
 (0)