1#![allow(clippy::result_unit_err)]
6
7use std::borrow::Borrow;
8use std::cell::RefCell;
9use std::iter::Rev;
10
11use crate::node_data_ref::NodeDataRef;
12use crate::select::Selectors;
13use crate::tree::{ElementData, NodeRef};
14
15impl NodeRef {
16 #[inline]
18 pub fn inclusive_ancestors(&self) -> Ancestors {
19 Ancestors(Some(self.clone()))
20 }
21
22 #[inline]
24 pub fn ancestors(&self) -> Ancestors {
25 Ancestors(self.parent())
26 }
27
28 #[inline]
30 pub fn inclusive_preceding_siblings(&self) -> Rev<Siblings> {
31 match self.parent() {
32 Some(parent) => {
33 let first_sibling = parent.first_child().unwrap();
34 debug_assert!(self.previous_sibling().is_some() || *self == first_sibling);
35 Siblings(Some(State {
36 next: first_sibling,
37 next_back: self.clone(),
38 }))
39 }
40 None => {
41 debug_assert!(self.previous_sibling().is_none());
42 Siblings(Some(State {
43 next: self.clone(),
44 next_back: self.clone(),
45 }))
46 }
47 }
48 .rev()
49 }
50
51 #[inline]
53 pub fn preceding_siblings(&self) -> Rev<Siblings> {
54 match (self.parent(), self.previous_sibling()) {
55 (Some(parent), Some(previous_sibling)) => {
56 let first_sibling = parent.first_child().unwrap();
57 Siblings(Some(State {
58 next: first_sibling,
59 next_back: previous_sibling,
60 }))
61 }
62 _ => Siblings(None),
63 }
64 .rev()
65 }
66
67 #[inline]
69 pub fn inclusive_following_siblings(&self) -> Siblings {
70 match self.parent() {
71 Some(parent) => {
72 let last_sibling = parent.last_child().unwrap();
73 debug_assert!(self.next_sibling().is_some() || *self == last_sibling);
74 Siblings(Some(State {
75 next: self.clone(),
76 next_back: last_sibling,
77 }))
78 }
79 None => {
80 debug_assert!(self.next_sibling().is_none());
81 Siblings(Some(State {
82 next: self.clone(),
83 next_back: self.clone(),
84 }))
85 }
86 }
87 }
88
89 #[inline]
91 pub fn following_siblings(&self) -> Siblings {
92 match (self.parent(), self.next_sibling()) {
93 (Some(parent), Some(next_sibling)) => {
94 let last_sibling = parent.last_child().unwrap();
95 Siblings(Some(State {
96 next: next_sibling,
97 next_back: last_sibling,
98 }))
99 }
100 _ => Siblings(None),
101 }
102 }
103
104 #[inline]
106 pub fn children(&self) -> Siblings {
107 match (self.first_child(), self.last_child()) {
108 (Some(first_child), Some(last_child)) => Siblings(Some(State {
109 next: first_child,
110 next_back: last_child,
111 })),
112 (None, None) => Siblings(None),
113 _ => unreachable!(),
114 }
115 }
116
117 #[inline]
123 pub fn inclusive_descendants(&self) -> Descendants {
124 Descendants(self.traverse_inclusive())
125 }
126
127 #[inline]
133 pub fn descendants(&self) -> Descendants {
134 Descendants(self.traverse())
135 }
136
137 #[inline]
140 pub fn traverse_inclusive(&self) -> Traverse {
141 Traverse(Some(State {
142 next: NodeEdge::Start(self.clone()),
143 next_back: NodeEdge::End(self.clone()),
144 }))
145 }
146
147 #[inline]
150 pub fn traverse(&self) -> Traverse {
151 match (self.first_child(), self.last_child()) {
152 (Some(first_child), Some(last_child)) => Traverse(Some(State {
153 next: NodeEdge::Start(first_child),
154 next_back: NodeEdge::End(last_child),
155 })),
156 (None, None) => Traverse(None),
157 _ => unreachable!(),
158 }
159 }
160
161 #[inline]
163 pub fn select(&self, selectors: &str) -> Result<Select<Elements<Descendants>>, ()> {
164 self.inclusive_descendants().select(selectors)
165 }
166
167 #[inline]
169 pub fn select_first(&self, selectors: &str) -> Result<NodeDataRef<ElementData>, ()> {
170 let mut elements = self.select(selectors)?;
171 elements.next().ok_or(())
172 }
173}
174
175#[derive(Debug, Clone)]
176struct State<T> {
177 next: T,
178 next_back: T,
179}
180
181#[derive(Debug, Clone)]
183pub struct Siblings(Option<State<NodeRef>>);
184
185macro_rules! siblings_next {
186 ($next: ident, $next_back: ident, $next_sibling: ident) => {
187 fn $next(&mut self) -> Option<NodeRef> {
188 #![allow(non_shorthand_field_patterns)]
189 self.0.take().map(
190 |State {
191 $next: next,
192 $next_back: next_back,
193 }| {
194 if let Some(sibling) = next.$next_sibling() {
195 if next != next_back {
196 self.0 = Some(State {
197 $next: sibling,
198 $next_back: next_back,
199 })
200 }
201 }
202 next
203 },
204 )
205 }
206 };
207}
208
209impl Iterator for Siblings {
210 type Item = NodeRef;
211 siblings_next!(next, next_back, next_sibling);
212}
213
214impl DoubleEndedIterator for Siblings {
215 siblings_next!(next_back, next, previous_sibling);
216}
217
218#[derive(Debug, Clone)]
220pub struct Ancestors(Option<NodeRef>);
221
222impl Iterator for Ancestors {
223 type Item = NodeRef;
224
225 #[inline]
226 fn next(&mut self) -> Option<NodeRef> {
227 self.0.take().inspect(|node| {
228 self.0 = node.parent();
229 })
230 }
231}
232
233#[derive(Debug, Clone)]
235pub struct Descendants(Traverse);
236
237macro_rules! descendants_next {
238 ($next: ident) => {
239 #[inline]
240 fn $next(&mut self) -> Option<NodeRef> {
241 loop {
242 match (self.0).$next() {
243 Some(NodeEdge::Start(node)) => return Some(node),
244 Some(NodeEdge::End(_)) => {}
245 None => return None,
246 }
247 }
248 }
249 };
250}
251
252impl Iterator for Descendants {
253 type Item = NodeRef;
254 descendants_next!(next);
255}
256
257impl DoubleEndedIterator for Descendants {
258 descendants_next!(next_back);
259}
260
261#[derive(Debug, Copy, Clone, PartialEq, Eq)]
263pub enum NodeEdge<T> {
264 Start(T),
268
269 End(T),
273}
274
275#[derive(Debug, Clone)]
277pub struct Traverse(Option<State<NodeEdge<NodeRef>>>);
278
279macro_rules! traverse_next {
280 ($next: ident, $next_back: ident, $first_child: ident, $next_sibling: ident, $Start: ident, $End: ident) => {
281 fn $next(&mut self) -> Option<NodeEdge<NodeRef>> {
282 #![allow(non_shorthand_field_patterns)]
283 self.0.take().map(
284 |State {
285 $next: next,
286 $next_back: next_back,
287 }| {
288 if next != next_back {
289 self.0 = match next {
290 NodeEdge::$Start(ref node) => match node.$first_child() {
291 Some(child) => Some(State {
292 $next: NodeEdge::$Start(child),
293 $next_back: next_back,
294 }),
295 None => Some(State {
296 $next: NodeEdge::$End(node.clone()),
297 $next_back: next_back,
298 }),
299 },
300 NodeEdge::$End(ref node) => match node.$next_sibling() {
301 Some(sibling) => Some(State {
302 $next: NodeEdge::$Start(sibling),
303 $next_back: next_back,
304 }),
305 None => node.parent().map(|parent| State {
306 $next: NodeEdge::$End(parent),
307 $next_back: next_back,
308 }),
309 },
310 };
311 }
312 next
313 },
314 )
315 }
316 };
317}
318
319impl Iterator for Traverse {
320 type Item = NodeEdge<NodeRef>;
321 traverse_next!(next, next_back, first_child, next_sibling, Start, End);
322}
323
324impl DoubleEndedIterator for Traverse {
325 traverse_next!(next_back, next, last_child, previous_sibling, End, Start);
326}
327
328macro_rules! filter_map_like_iterator {
329 (#[$doc: meta] $name: ident: $f: expr, $from: ty => $to: ty) => {
330 #[$doc]
331 #[derive(Debug, Clone)]
332 pub struct $name<I>(pub I);
333
334 impl<I> Iterator for $name<I>
335 where
336 I: Iterator<Item = $from>,
337 {
338 type Item = $to;
339
340 #[inline]
341 fn next(&mut self) -> Option<$to> {
342 for x in self.0.by_ref() {
343 if let Some(y) = ($f)(x) {
344 return Some(y);
345 }
346 }
347 None
348 }
349 }
350
351 impl<I> DoubleEndedIterator for $name<I>
352 where
353 I: DoubleEndedIterator<Item = $from>,
354 {
355 #[inline]
356 fn next_back(&mut self) -> Option<$to> {
357 for x in self.0.by_ref().rev() {
358 if let Some(y) = ($f)(x) {
359 return Some(y);
360 }
361 }
362 None
363 }
364 }
365 };
366}
367
368filter_map_like_iterator! {
369 Elements: NodeRef::into_element_ref, NodeRef => NodeDataRef<ElementData>
371}
372
373filter_map_like_iterator! {
374 Comments: NodeRef::into_comment_ref, NodeRef => NodeDataRef<RefCell<String>>
376}
377
378filter_map_like_iterator! {
379 TextNodes: NodeRef::into_text_ref, NodeRef => NodeDataRef<RefCell<String>>
381}
382
383pub struct Select<I, S = Selectors>
385where
386 I: Iterator<Item = NodeDataRef<ElementData>>,
387 S: Borrow<Selectors>,
388{
389 pub iter: I,
391
392 pub selectors: S,
394}
395
396impl<I, S> Iterator for Select<I, S>
397where
398 I: Iterator<Item = NodeDataRef<ElementData>>,
399 S: Borrow<Selectors>,
400{
401 type Item = NodeDataRef<ElementData>;
402
403 #[inline]
404 fn next(&mut self) -> Option<NodeDataRef<ElementData>> {
405 let selectors = self.selectors.borrow();
406 self.iter
407 .by_ref()
408 .find(|element| selectors.matches(element))
409 }
410}
411
412impl<I, S> DoubleEndedIterator for Select<I, S>
413where
414 I: DoubleEndedIterator<Item = NodeDataRef<ElementData>>,
415 S: Borrow<Selectors>,
416{
417 #[inline]
418 fn next_back(&mut self) -> Option<NodeDataRef<ElementData>> {
419 let selectors = self.selectors.borrow();
420 self.iter
421 .by_ref()
422 .rev()
423 .find(|element| selectors.matches(element))
424 }
425}
426
427pub trait NodeIterator: Sized + Iterator<Item = NodeRef> {
429 #[inline]
431 fn elements(self) -> Elements<Self> {
432 Elements(self)
433 }
434
435 #[inline]
437 fn text_nodes(self) -> TextNodes<Self> {
438 TextNodes(self)
439 }
440
441 #[inline]
443 fn comments(self) -> Comments<Self> {
444 Comments(self)
445 }
446
447 #[inline]
449 fn select(self, selectors: &str) -> Result<Select<Elements<Self>>, ()> {
450 self.elements().select(selectors)
451 }
452}
453
454pub trait ElementIterator: Sized + Iterator<Item = NodeDataRef<ElementData>> {
456 #[inline]
458 fn select(self, selectors: &str) -> Result<Select<Self>, ()> {
459 Selectors::compile(selectors).map(|s| Select {
460 iter: self,
461 selectors: s,
462 })
463 }
464}
465
466impl<I> NodeIterator for I where I: Iterator<Item = NodeRef> {}
467impl<I> ElementIterator for I where I: Iterator<Item = NodeDataRef<ElementData>> {}