Skip to content

Commit 72e73f4

Browse files
committed
Fix reparent methods to update parent for all siblings
Previously only first and last siblings had their parent updated, leaving middle siblings with stale parent references.
1 parent 2a90702 commit 72e73f4

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

src/lib.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,9 +843,12 @@ 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+
// Update parent for all siblings in the chain
847+
let mut child_id = new_child_ids.0;
848+
loop {
849+
unsafe { self.tree.node_mut(child_id).parent = Some(self.id); }
850+
if child_id == new_child_ids.1 { break; }
851+
child_id = unsafe { self.tree.node_mut(child_id).next_sibling.unwrap() };
849852
}
850853

851854
if self.node().children.is_none() {
@@ -882,9 +885,12 @@ impl<'a, T: 'a> NodeMut<'a, T> {
882885
}
883886
};
884887

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);
888+
// Update parent for all siblings in the chain
889+
let mut child_id = new_child_ids.0;
890+
loop {
891+
unsafe { self.tree.node_mut(child_id).parent = Some(self.id); }
892+
if child_id == new_child_ids.1 { break; }
893+
child_id = unsafe { self.tree.node_mut(child_id).next_sibling.unwrap() };
888894
}
889895

890896
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)