use dmc_parser::ast::*;
pub enum NodeAction {
Keep,
KeepSkipChildren,
Replace(Vec<Node>),
Remove,
}
pub trait Visitor {
fn visit_node(&mut self, _node: &mut Node) -> NodeAction {
NodeAction::Keep
}
}
pub fn walk_children_mut<V: Visitor>(parent: &mut Node, v: &mut V) {
if let Node::Table(t) = parent {
for row in &mut t.children {
for cell in &mut row.cells {
walk_root(&mut cell.children, v);
}
}
return;
}
if let Some(kids) = Node::children_of_mut(parent) {
walk_root(kids, v);
}
}
pub fn walk_root<V: Visitor>(children: &mut Vec<Node>, v: &mut V) {
let mut i = 0;
while i < children.len() {
match v.visit_node(&mut children[i]) {
NodeAction::Keep => {
walk_children_mut(&mut children[i], v);
i += 1;
},
NodeAction::KeepSkipChildren => {
i += 1;
},
NodeAction::Replace(new) => {
let n = new.len();
children.splice(i..=i, new);
i += n;
},
NodeAction::Remove => {
children.remove(i);
},
}
}
}