textlane_html/actions/hast/
visit.rs1use textlane_core::hast::{Element, Node};
2
3use crate::models::visit::Visit;
4
5pub fn visit_elements<'a>(
8 node: &mut Node<'a>,
9 mut visitor: impl FnMut(&mut Element<'a>, &[&'a str]) -> Visit,
10) {
11 let mut ancestors: Vec<&'a str> = vec![];
12 let mut stack: Vec<(&mut Node<'a>, usize)> = vec![(node, 0)];
14 while let Some((node, depth)) = stack.pop() {
15 ancestors.truncate(depth);
16 let children = match node {
17 Node::Root(root) => &mut root.children,
18 Node::Element(element) => {
19 match visitor(element, &ancestors) {
20 Visit::Stop => return,
21 Visit::Skip => continue,
22 Visit::Continue => {}
23 }
24 ancestors.push(element.tag_name);
25 &mut element.children
26 }
27 _ => continue,
28 };
29 let depth = ancestors.len();
30 for child in children.iter_mut().rev() {
31 stack.push((child, depth));
32 }
33 }
34}
35
36#[cfg(test)]
37#[path = "visit_unit.rs"]
38mod unit;