tl/queryselector/
iter.rs

1use std::marker::PhantomData;
2
3use crate::{NodeHandle, Parser};
4
5use super::{iterable::QueryIterable, Selector};
6
7/// A query selector iterator that yields matching HTML nodes
8pub struct QuerySelectorIterator<'a, 'b, Q: QueryIterable<'a>> {
9    selector: Selector<'b>,
10    collection: &'b Q,
11    parser: &'b Parser<'a>,
12    index: usize,
13    len: usize,
14    _a: PhantomData<&'a ()>,
15}
16
17impl<'a, 'b, Q: QueryIterable<'a>> Clone for QuerySelectorIterator<'a, 'b, Q> {
18    fn clone(&self) -> Self {
19        Self {
20            selector: self.selector.clone(),
21            collection: self.collection,
22            parser: self.parser,
23            index: self.index,
24            len: self.len,
25            _a: PhantomData,
26        }
27    }
28}
29
30impl<'a, 'b, Q: QueryIterable<'a>> QuerySelectorIterator<'a, 'b, Q> {
31    /// Creates a new query selector iterator
32    pub fn new(selector: Selector<'b>, parser: &'b Parser<'a>, collection: &'b Q) -> Self {
33        Self {
34            selector,
35            collection,
36            index: 0,
37            len: collection.len(parser),
38            parser,
39            _a: PhantomData,
40        }
41    }
42}
43
44impl<'a, 'b, Q: QueryIterable<'a>> Iterator for QuerySelectorIterator<'a, 'b, Q> {
45    type Item = NodeHandle;
46
47    fn next(&mut self) -> Option<Self::Item> {
48        while self.index < self.len {
49            let node = self.collection.get(self.parser, self.index);
50            self.index += 1;
51            if let Some((node, id)) = node {
52                let matches = self.selector.matches(node);
53
54                if matches {
55                    return Some(id);
56                }
57            }
58        }
59
60        None
61    }
62}