scah/selection_engine/
multiplexer.rs1use std::fmt::Debug;
2
3use super::executor::QueryExecutor;
4use crate::XHtmlElement;
5use crate::css::selector::Query;
6use crate::store::Store;
7
8pub(crate) struct DocumentPosition {
9 pub reader_position: usize,
10 pub text_content_position: usize,
11 pub element_depth: crate::selection_engine::DepthSize,
12}
13
14type Runner<'query> = Vec<QueryExecutor<'query, 'query>>;
16
17#[derive(Debug)]
18pub struct QueryMultiplexer<'query> {
19 runners: Runner<'query>,
20}
21
22impl<'html, 'query: 'html> QueryMultiplexer<'query> {
23 pub fn new(queries: &'query [Query<'query>]) -> Self {
24 Self {
25 #[allow(clippy::redundant_closure)]
26 runners: queries
27 .iter()
28 .map(|query| QueryExecutor::new(query))
29 .collect::<Runner<'query>>(),
30 }
31 }
32
33 pub(crate) fn next(
34 &mut self,
35 xhtml_element: &XHtmlElement<'html>,
36 position: &DocumentPosition,
37 store: &mut Store<'html, 'query>,
38 ) {
39 let len = store.elements.len();
40 for session in self.runners.iter_mut() {
41 session.next(xhtml_element, position, store);
42 }
43 if len == store.elements.len() {
44 xhtml_element.remove_attributes(&mut store.attributes);
47 }
48 }
49
50 pub(crate) fn back(
51 &mut self,
52 xhtml_element: &'html str,
53 position: &DocumentPosition,
54 reader: &crate::utils::Reader<'html>,
55 store: &mut Store<'html, 'query>,
56 ) -> bool {
57 let mut remove_indices = vec![];
58 for (index, session) in self.runners.iter_mut().enumerate() {
59 let early_exit = session.early_exit();
60 let back = session.back(store, xhtml_element, position, reader);
61
62 if early_exit && back {
63 remove_indices.push(index);
64 }
65 }
66 for idx in remove_indices {
67 self.runners.remove(idx);
68 }
69
70 self.runners.is_empty()
71 }
72}