Skip to content

Commit

Permalink
Allow a soft delete of a node
Browse files Browse the repository at this point in the history
Dearest reviewer,

thank you for your work on this project. This is a proof of concept of a
soft delete. It doesnt cover all calls like data. I was just worried
about text.

Becker
  • Loading branch information
sbeckeriv committed Oct 15, 2020
1 parent 52f6304 commit da9b245
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
56 changes: 41 additions & 15 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,32 @@ pub struct Raw {
pub struct Node<'a> {
document: &'a Document,
index: usize,
pub deleted: bool,
}

impl<'a> Node<'a> {
/// Create a Node referring to the `index`th Node of a document.
pub fn new(document: &'a Document, index: usize) -> Option<Node<'a>> {
if index < document.nodes.len() {
Some(Node { document, index })
Some(Node {
document,
index,
deleted: false,
})
} else {
None
}
}

// soft delete
pub fn delete(&mut self) {
self.deleted = true;
}
// unremove it
pub fn undelete(&mut self) {
self.deleted = false;
}

/// Get the index of this Node in its Document.
pub fn index(&self) -> usize {
self.index
Expand Down Expand Up @@ -126,15 +140,19 @@ impl<'a> Node<'a> {
/// Get the combined textual content of a Node and all of its children.
pub fn text(&self) -> String {
let mut string = String::new();
recur(self, &mut string);
return string;
if self.deleted {
string
} else {
recur(self, &mut string);
return string;

fn recur(node: &Node, string: &mut String) {
if let Some(text) = node.as_text() {
string.push_str(text);
}
for child in node.children() {
recur(&child, string)
fn recur(node: &Node, string: &mut String) {
if let Some(text) = node.as_text() {
string.push_str(text);
}
for child in node.children() {
recur(&child, string)
}
}
}
}
Expand Down Expand Up @@ -171,17 +189,25 @@ impl<'a> Node<'a> {

/// Get the text of a text Node, or None if the node is not text.
pub fn as_text(&self) -> Option<&'a str> {
match *self.data() {
Data::Text(ref text) => Some(&text),
_ => None,
if self.deleted {
Some("")
} else {
match *self.data() {
Data::Text(ref text) => Some(&text),
_ => None,
}
}
}

/// Get the text of a comment Node, or None if the node is not a comment.
pub fn as_comment(&self) -> Option<&'a str> {
match *self.data() {
Data::Comment(ref comment) => Some(&comment),
_ => None,
if self.deleted {
Some("")
} else {
match *self.data() {
Data::Comment(ref comment) => Some(&comment),
_ => None,
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion tests/node_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ speculate! {
foo<bar>baz<quux class=another-thing>\
<!--comment-->");

let html = document.nth(0).unwrap();
let mut html = document.nth(0).unwrap();
let head = document.nth(1).unwrap();
let body = document.nth(2).unwrap();
let foo = document.nth(3).unwrap();
Expand Down Expand Up @@ -117,6 +117,8 @@ speculate! {

test "Node::text()" {
assert_eq!(html.text(), "foobaz");
html.delete();
assert_eq!(html.text(), "");
assert_eq!(head.text(), "");
assert_eq!(body.text(), "foobaz");
assert_eq!(foo.text(), "foo");
Expand Down

0 comments on commit da9b245

Please sign in to comment.