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#[derive(Clone)]
26pub struct Interpreter {
27 pub document: NodeHandle,
29
30 pub result: SelectionResult,
32
33 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 fn reset_selection(&mut self) {
52 self.result = SelectionResult::with_nodes(vec![self.document.clone()]);
53 }
54
55
56 pub fn select(&mut self, selector: &str) -> InterpreterResult<SelectionResult> {
58 let ast = parse(selector).map_err(|e| InterpreterError::ParserError(e.to_string()))?;
60
61 if !self.is_first_interpret {
64 self.reset_selection();
65 } else {
66 self.is_first_interpret = false;
68 }
69
70 ast.accept(self)?;
71
72 Ok(self.result.clone())
74 }
75
76
77
78
79 pub fn select_from(
81 &mut self,
82 context: &SelectionResult,
83 selector: &str,
84 ) -> InterpreterResult<SelectionResult> {
85 let original_result = self.result.clone();
87 let was_first = self.is_first_interpret;
88
89 self.result = context.clone();
91 self.is_first_interpret = false; 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 self.result = original_result;
101 self.is_first_interpret = was_first;
102
103 Ok(result)
104 }
105}
106
107impl 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}