Skip to content

Commit

Permalink
src/node/serializing.rs: revise SerializableNodeRef
Browse files Browse the repository at this point in the history
  • Loading branch information
niklak committed Oct 26, 2024
1 parent ec296cb commit 41e46a6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 27 deletions.
66 changes: 40 additions & 26 deletions src/node/serializing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use super::node_data::NodeData;
use super::node_ref::{Node, NodeRef};
use super::NodeId;

enum SerializeOp {
enum SerializeOp<'a> {
Open(NodeId),
Close(QualName),
Close(&'a QualName),
}
/// Serializable wrapper of Node.
pub struct SerializableNodeRef<'a>(Node<'a>);
Expand All @@ -28,37 +28,45 @@ impl<'a> Serialize for SerializableNodeRef<'a> {
{
let nodes = self.0.tree.nodes.borrow();
let id = self.0.id;

// Initialize ops stack
let mut ops = match traversal_scope {
TraversalScope::IncludeNode => vec![SerializeOp::Open(id)],
TraversalScope::ChildrenOnly(_) => self
.0
.tree
.child_ids_of_it(&id)
.map(SerializeOp::Open)
.collect(),
TraversalScope::ChildrenOnly(_) => {
// For children only, add all child nodes
self.0
.tree
.child_ids_of(&id)
.into_iter()
.rev()
.map(SerializeOp::Open)
.collect()
}
};

while !ops.is_empty() {
match ops.remove(0) {
while let Some(op) = ops.pop() {
match op {
SerializeOp::Open(id) => {
let node_opt = &nodes.get(id.value);
let node = match node_opt {
let node = match nodes.get(id.value) {
Some(node) => node,
None => continue,
};

match node.data {
NodeData::Element(ref e) => {
match &node.data {
NodeData::Element(e) => {
serializer.start_elem(
e.name.clone(),
e.attrs.iter().map(|at| (&at.name, &at.value[..])),
)?;

ops.insert(0, SerializeOp::Close(e.name.clone()));

for child_id in self.0.tree.child_ids_of(&id).into_iter().rev() {
ops.insert(0, SerializeOp::Open(child_id));
}
ops.push(SerializeOp::Close(&e.name));
ops.extend(
self.0
.tree
.child_ids_of(&id)
.into_iter()
.rev()
.map(SerializeOp::Open),
);

Ok(())
}
Expand All @@ -70,15 +78,21 @@ impl<'a> Serialize for SerializableNodeRef<'a> {
ref contents,
} => serializer.write_processing_instruction(target, contents),
NodeData::Document | NodeData::Fragment => {
for child_id in self.0.tree.child_ids_of(&id).into_iter().rev() {
ops.insert(0, SerializeOp::Open(child_id));
}
// Push children in reverse order
ops.extend(
self.0
.tree
.child_ids_of(&id)
.into_iter()
.rev()
.map(SerializeOp::Open),
);
continue;
}
}
}?;
}
SerializeOp::Close(name) => serializer.end_elem(name),
}?
SerializeOp::Close(name) => serializer.end_elem(name.clone())?,
}
}

Ok(())
Expand Down
1 change: 0 additions & 1 deletion tests/selection-traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ fn test_ancestor_iter_with_limit() {
let child_node = child_sel.nodes().first().unwrap();
let ancestors = child_node.ancestors_it(Some(2));
// utilizing ancestors iterator (without intermediate collection)

// got 2 ancestors
assert!(ancestors.count() == 2);
}

0 comments on commit 41e46a6

Please sign in to comment.