htmls/interpreter/
mod.rs

1pub mod element;
2pub mod error;
3pub mod function;
4pub mod html;
5pub mod index;
6pub mod pipeline;
7pub mod result;
8pub mod set;
9pub mod text;
10
11use super::{
12    parse,
13    parser::{
14        ElementNode, FunctionNode, IndexNode, Node, SelectorNode, SetOperationNode, TextNode,
15        Visitable, Visitor,
16    },
17};
18
19pub use error::{InterpreterError, InterpreterResult};
20pub use result::{NodeHandle, SelectionResult};
21
22
23
24/// HTML selector interpreter
25#[derive(Clone)]
26pub struct Interpreter {
27    /// HTML document tree root node
28    pub document: NodeHandle,
29
30    /// Current selection result
31    pub result: SelectionResult,
32
33    /// Flag indicating if it's the first interpretation
34    pub is_first_interpret: bool,
35}
36
37impl Interpreter {
38
39    pub fn new(html: &str) -> InterpreterResult<Self> {
40
41        let document = html::parse_html(html)?;
42
43        Ok(Interpreter {
44            document: document.clone(),
45            result: SelectionResult::with_nodes(vec![document]),
46            is_first_interpret: true,
47        })
48    }
49
50    /// Reset selection state
51    fn reset_selection(&mut self) {
52        self.result = SelectionResult::with_nodes(vec![self.document.clone()]);
53    }
54
55
56    /// Select matching nodes
57    pub fn select(&mut self, selector: &str) -> InterpreterResult<SelectionResult> {
58        // Parse selector into AST
59        let ast = parse(selector).map_err(|e| InterpreterError::ParserError(e.to_string()))?;
60
61        // No need to reset on first call, already initialized in new()
62        // Need to reset selection state for subsequent calls
63        if !self.is_first_interpret {
64            self.reset_selection();
65        } else {
66            // Mark as no longer first interpretation
67            self.is_first_interpret = false;
68        }
69
70        ast.accept(self)?;
71
72        // Create and return a copy of the result
73        Ok(self.result.clone())
74    }
75
76
77
78
79    /// Select nodes in specified context
80    pub fn select_from(
81        &mut self,
82        context: &SelectionResult,
83        selector: &str,
84    ) -> InterpreterResult<SelectionResult> {
85        // Save original state
86        let original_result = self.result.clone();
87        let was_first = self.is_first_interpret;
88
89        // Set context as current result
90        self.result = context.clone();
91        self.is_first_interpret = false; // Ensure selection state is not reset
92
93
94        let ast = parse(selector).map_err(|e| InterpreterError::ParserError(e.to_string()))?;
95        self.visit_node(&ast)?;
96
97        let result = self.result.clone();
98
99        // Restore original state
100        self.result = original_result;
101        self.is_first_interpret = was_first;
102
103        Ok(result)
104    }
105}
106
107/// Implement Visitor trait to traverse and execute AST
108impl Visitor<InterpreterResult<()>> for Interpreter {
109    fn visit_node(&mut self, node: &Node) -> InterpreterResult<()> {
110        match node {
111            Node::Selector(selector) => self.visit_selector(selector),
112            Node::Pipeline(left, right) => self.visit_pipeline(left, right),
113            Node::IndexSelection(inner, index) => {
114                self.visit_node(inner)?;
115                self.visit_index(index)
116            }
117            Node::SetOperation(op) => {
118                self.visit_set_operation(op)
119            }
120            Node::FunctionCall(inner, func) => {
121                self.visit_node(inner)?;
122                self.visit_function(func)
123            }
124        }
125    }
126
127    fn visit_selector(&mut self, selector: &SelectorNode) -> InterpreterResult<()> {
128        match selector {
129            SelectorNode::ElementSelector(elem) => self.visit_element(elem),
130            SelectorNode::TextSelector(text) => self.visit_text(text),
131        }
132    }
133
134    fn visit_element(&mut self, elem: &ElementNode) -> InterpreterResult<()> {
135        element::apply_element_selector(self, elem)?;
136        Ok(())
137    }
138
139    fn visit_text(&mut self, text: &TextNode) -> InterpreterResult<()> {
140        text::apply_text_selector(self, text)?;
141        Ok(())
142    }
143
144    fn visit_set_operation(&mut self, node: &SetOperationNode) -> InterpreterResult<()> {
145        set::apply_set_operation(self, node)?;
146        Ok(())
147    }
148
149    fn visit_index(&mut self, node: &IndexNode) -> InterpreterResult<()> {
150        index::apply_index_selection(self, node)?;
151        Ok(())
152    }
153
154    fn visit_function(&mut self, node: &FunctionNode) -> InterpreterResult<()> {
155        function::apply_function(self, node)?;
156        Ok(())
157    }
158
159    fn visit_pipeline(&mut self, left: &Node, right: &Node) -> InterpreterResult<()> {
160        pipeline::apply_pipeline(self, left, right)?;
161        Ok(())
162    }
163}