1use core::marker::PhantomData;
2
3use crate::{NodeHandle, Parser};
4
5use super::{Selector, iterable::QueryIterable};
6
7pub struct QuerySelectorIterator<
9 'a,
10 'b,
11 Q: QueryIterable<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
12 const MAX_NODES: usize = 0,
13 const MAX_STACK: usize = 0,
14 const MAX_ROOTS: usize = 0,
15 const MAX_IDS: usize = 0,
16 const MAX_CLASSES: usize = 0,
17 const MAX_SELECTOR_NODES: usize = 0,
18> {
19 selector: Selector<'b, MAX_SELECTOR_NODES>,
20 collection: &'b Q,
21 parser:
22 &'b Parser<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
23 #[cfg(feature = "std")]
24 context: Option<super::selector::Context>,
25 index: usize,
26 len: usize,
27 _a: PhantomData<&'a ()>,
28}
29
30impl<
31 'a,
32 'b,
33 Q: QueryIterable<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
34 const MAX_NODES: usize,
35 const MAX_STACK: usize,
36 const MAX_ROOTS: usize,
37 const MAX_IDS: usize,
38 const MAX_CLASSES: usize,
39 const MAX_SELECTOR_NODES: usize,
40> Clone
41 for QuerySelectorIterator<
42 'a,
43 'b,
44 Q,
45 MAX_NODES,
46 MAX_STACK,
47 MAX_ROOTS,
48 MAX_IDS,
49 MAX_CLASSES,
50 MAX_SELECTOR_NODES,
51 >
52{
53 fn clone(&self) -> Self {
54 Self {
55 selector: self.selector.clone(),
56 #[cfg(feature = "std")]
57 context: self.context.clone(),
58 collection: self.collection,
59 parser: self.parser,
60 index: self.index,
61 len: self.len,
62 _a: PhantomData,
63 }
64 }
65}
66
67impl<
68 'a,
69 'b,
70 Q: QueryIterable<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
71 const MAX_NODES: usize,
72 const MAX_STACK: usize,
73 const MAX_ROOTS: usize,
74 const MAX_IDS: usize,
75 const MAX_CLASSES: usize,
76 const MAX_SELECTOR_NODES: usize,
77>
78 QuerySelectorIterator<
79 'a,
80 'b,
81 Q,
82 MAX_NODES,
83 MAX_STACK,
84 MAX_ROOTS,
85 MAX_IDS,
86 MAX_CLASSES,
87 MAX_SELECTOR_NODES,
88 >
89{
90 pub fn new(
92 selector: Selector<'b, MAX_SELECTOR_NODES>,
93 parser: &'b Parser<
94 'a,
95 MAX_NODES,
96 MAX_STACK,
97 MAX_ROOTS,
98 MAX_IDS,
99 MAX_CLASSES,
100 MAX_SELECTOR_NODES,
101 >,
102 collection: &'b Q,
103 ) -> Self {
104 Self {
105 #[cfg(feature = "std")]
106 context: selector
107 .needs_context()
108 .then(|| super::selector::Context::new(parser.tags.as_slice())),
109 selector,
110 collection,
111 index: 0,
112 len: collection.len(parser),
113 parser,
114 _a: PhantomData,
115 }
116 }
117}
118
119impl<
120 'a,
121 'b,
122 Q: QueryIterable<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
123 const MAX_NODES: usize,
124 const MAX_STACK: usize,
125 const MAX_ROOTS: usize,
126 const MAX_IDS: usize,
127 const MAX_CLASSES: usize,
128 const MAX_SELECTOR_NODES: usize,
129> Iterator
130 for QuerySelectorIterator<
131 'a,
132 'b,
133 Q,
134 MAX_NODES,
135 MAX_STACK,
136 MAX_ROOTS,
137 MAX_IDS,
138 MAX_CLASSES,
139 MAX_SELECTOR_NODES,
140 >
141{
142 type Item = NodeHandle;
143
144 fn next(&mut self) -> Option<Self::Item> {
145 while self.index < self.len {
146 let node = self.collection.get(self.parser, self.index);
147 self.index += 1;
148 if let Some((node, id)) = node {
149 #[cfg(feature = "std")]
150 let matches = self.context.as_ref().map_or_else(
151 || self.selector.matches(node),
152 |context| {
153 self.selector.matches_in(
154 id.get_inner() as usize,
155 self.parser.tags.as_slice(),
156 context,
157 )
158 },
159 );
160 #[cfg(not(feature = "std"))]
161 let matches = self.selector.matches(node);
162
163 if matches {
164 return Some(id);
165 }
166 }
167 }
168
169 None
170 }
171}