Skip to content

Commit b8adcd1

Browse files
authored
Merge pull request #40 from rust-scraper/noop-prepend-append-id
Do not produce invalid trees when no-op instances of append_id or prepend_id operations are performed.
2 parents 8127d31 + 8aba49f commit b8adcd1

File tree

2 files changed

+64
-30
lines changed

2 files changed

+64
-30
lines changed

src/lib.rs

+36-30
Original file line numberDiff line numberDiff line change
@@ -557,24 +557,27 @@ impl<'a, T: 'a> NodeMut<'a, T> {
557557
);
558558

559559
let last_child_id = self.node().children.map(|(_, id)| id);
560-
{
561-
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
562-
new_child.detach();
563-
new_child.node().parent = Some(self.id);
564-
new_child.node().prev_sibling = last_child_id;
565-
}
566560

567-
if let Some(id) = last_child_id {
568-
unsafe {
569-
self.tree.node_mut(id).next_sibling = Some(new_child_id);
561+
if last_child_id != Some(new_child_id) {
562+
{
563+
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
564+
new_child.detach();
565+
new_child.node().parent = Some(self.id);
566+
new_child.node().prev_sibling = last_child_id;
570567
}
571-
}
572568

573-
{
574-
self.node().children = match self.node().children {
575-
Some((first_child_id, _)) => Some((first_child_id, new_child_id)),
576-
None => Some((new_child_id, new_child_id)),
577-
};
569+
if let Some(id) = last_child_id {
570+
unsafe {
571+
self.tree.node_mut(id).next_sibling = Some(new_child_id);
572+
}
573+
}
574+
575+
{
576+
self.node().children = match self.node().children {
577+
Some((first_child_id, _)) => Some((first_child_id, new_child_id)),
578+
None => Some((new_child_id, new_child_id)),
579+
};
580+
}
578581
}
579582

580583
unsafe { self.tree.get_unchecked_mut(new_child_id) }
@@ -593,24 +596,27 @@ impl<'a, T: 'a> NodeMut<'a, T> {
593596
);
594597

595598
let first_child_id = self.node().children.map(|(id, _)| id);
596-
{
597-
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
598-
new_child.detach();
599-
new_child.node().parent = Some(self.id);
600-
new_child.node().next_sibling = first_child_id;
601-
}
602599

603-
if let Some(id) = first_child_id {
604-
unsafe {
605-
self.tree.node_mut(id).prev_sibling = Some(new_child_id);
600+
if first_child_id != Some(new_child_id) {
601+
{
602+
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
603+
new_child.detach();
604+
new_child.node().parent = Some(self.id);
605+
new_child.node().next_sibling = first_child_id;
606606
}
607-
}
608607

609-
{
610-
self.node().children = match self.node().children {
611-
Some((_, last_child_id)) => Some((new_child_id, last_child_id)),
612-
None => Some((new_child_id, new_child_id)),
613-
};
608+
if let Some(id) = first_child_id {
609+
unsafe {
610+
self.tree.node_mut(id).prev_sibling = Some(new_child_id);
611+
}
612+
}
613+
614+
{
615+
self.node().children = match self.node().children {
616+
Some((_, last_child_id)) => Some((new_child_id, last_child_id)),
617+
None => Some((new_child_id, new_child_id)),
618+
};
619+
}
614620
}
615621

616622
unsafe { self.tree.get_unchecked_mut(new_child_id) }

tests/node_mut.rs

+28
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,20 @@ fn append_id_itself() {
325325
e.append_id(e.id());
326326
}
327327

328+
#[test]
329+
fn append_id_noop() {
330+
let mut tree = tree! {
331+
'a' => {
332+
'b' => { 'c', 'd' },
333+
'e' => { 'f', 'g' },
334+
}
335+
};
336+
let mut a = tree.root_mut();
337+
let e_id = a.last_child().unwrap().id();
338+
a.append_id(e_id);
339+
assert_eq!(a.first_child().unwrap().next_sibling().unwrap().id(), e_id);
340+
}
341+
328342
#[test]
329343
#[should_panic(expected = "Cannot prepend node as a child to itself")]
330344
fn prepend_id_itself() {
@@ -339,6 +353,20 @@ fn prepend_id_itself() {
339353
e.prepend_id(e.id());
340354
}
341355

356+
#[test]
357+
fn prepend_id_noop() {
358+
let mut tree = tree! {
359+
'a' => {
360+
'b' => { 'c', 'd' },
361+
'e' => { 'f', 'g' },
362+
}
363+
};
364+
let mut a = tree.root_mut();
365+
let b_id = a.first_child().unwrap().id();
366+
a.prepend_id(b_id);
367+
assert_eq!(a.last_child().unwrap().prev_sibling().unwrap().id(), b_id);
368+
}
369+
342370
#[test]
343371
fn reparent_from_id_append() {
344372
let mut tree = tree! {

0 commit comments

Comments
 (0)