accesskit_consumer/
iterators.rs

1// Copyright 2021 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6// Derived from Chromium's accessibility abstraction.
7// Copyright 2018 The Chromium Authors. All rights reserved.
8// Use of this source code is governed by a BSD-style license that can be
9// found in the LICENSE.chromium file.
10
11use std::iter::FusedIterator;
12
13use accesskit::NodeId;
14
15use crate::{filters::FilterResult, node::Node, tree::State as TreeState};
16
17/// An iterator that yields following siblings of a node.
18///
19/// This struct is created by the [`following_siblings`](Node::following_siblings) method on [`Node`].
20pub struct FollowingSiblings<'a> {
21    back_position: usize,
22    done: bool,
23    front_position: usize,
24    parent: Option<Node<'a>>,
25}
26
27impl<'a> FollowingSiblings<'a> {
28    pub(crate) fn new(node: Node<'a>) -> Self {
29        let parent_and_index = node.parent_and_index();
30        let (back_position, front_position, done) =
31            if let Some((ref parent, index)) = parent_and_index {
32                let back_position = parent.data().children().len() - 1;
33                let front_position = index + 1;
34                (
35                    back_position,
36                    front_position,
37                    front_position > back_position,
38                )
39            } else {
40                (0, 0, true)
41            };
42        Self {
43            back_position,
44            done,
45            front_position,
46            parent: parent_and_index.map(|(parent, _)| parent),
47        }
48    }
49}
50
51impl<'a> Iterator for FollowingSiblings<'a> {
52    type Item = NodeId;
53
54    fn next(&mut self) -> Option<Self::Item> {
55        if self.done {
56            None
57        } else {
58            self.done = self.front_position == self.back_position;
59            let child = self
60                .parent
61                .as_ref()?
62                .data()
63                .children()
64                .get(self.front_position)?;
65            self.front_position += 1;
66            Some(*child)
67        }
68    }
69
70    fn size_hint(&self) -> (usize, Option<usize>) {
71        let len = match self.done {
72            true => 0,
73            _ => self.back_position + 1 - self.front_position,
74        };
75        (len, Some(len))
76    }
77}
78
79impl<'a> DoubleEndedIterator for FollowingSiblings<'a> {
80    fn next_back(&mut self) -> Option<Self::Item> {
81        if self.done {
82            None
83        } else {
84            self.done = self.back_position == self.front_position;
85            let child = self
86                .parent
87                .as_ref()?
88                .data()
89                .children()
90                .get(self.back_position)?;
91            self.back_position -= 1;
92            Some(*child)
93        }
94    }
95}
96
97impl<'a> ExactSizeIterator for FollowingSiblings<'a> {}
98
99impl<'a> FusedIterator for FollowingSiblings<'a> {}
100
101/// An iterator that yields preceding siblings of a node.
102///
103/// This struct is created by the [`preceding_siblings`](Node::preceding_siblings) method on [`Node`].
104pub struct PrecedingSiblings<'a> {
105    back_position: usize,
106    done: bool,
107    front_position: usize,
108    parent: Option<Node<'a>>,
109}
110
111impl<'a> PrecedingSiblings<'a> {
112    pub(crate) fn new(node: Node<'a>) -> Self {
113        let parent_and_index = node.parent_and_index();
114        let (back_position, front_position, done) = if let Some((_, index)) = parent_and_index {
115            let front_position = index.saturating_sub(1);
116            (0, front_position, index == 0)
117        } else {
118            (0, 0, true)
119        };
120        Self {
121            back_position,
122            done,
123            front_position,
124            parent: parent_and_index.map(|(parent, _)| parent),
125        }
126    }
127}
128
129impl<'a> Iterator for PrecedingSiblings<'a> {
130    type Item = NodeId;
131
132    fn next(&mut self) -> Option<Self::Item> {
133        if self.done {
134            None
135        } else {
136            self.done = self.front_position == self.back_position;
137            let child = self
138                .parent
139                .as_ref()?
140                .data()
141                .children()
142                .get(self.front_position)?;
143            if !self.done {
144                self.front_position -= 1;
145            }
146            Some(*child)
147        }
148    }
149
150    fn size_hint(&self) -> (usize, Option<usize>) {
151        let len = match self.done {
152            true => 0,
153            _ => self.front_position + 1 - self.back_position,
154        };
155        (len, Some(len))
156    }
157}
158
159impl<'a> DoubleEndedIterator for PrecedingSiblings<'a> {
160    fn next_back(&mut self) -> Option<Self::Item> {
161        if self.done {
162            None
163        } else {
164            self.done = self.back_position == self.front_position;
165            let child = self
166                .parent
167                .as_ref()?
168                .data()
169                .children()
170                .get(self.back_position)?;
171            self.back_position += 1;
172            Some(*child)
173        }
174    }
175}
176
177impl<'a> ExactSizeIterator for PrecedingSiblings<'a> {}
178
179impl<'a> FusedIterator for PrecedingSiblings<'a> {}
180
181fn next_filtered_sibling<'a>(
182    node: Option<Node<'a>>,
183    filter: &impl Fn(&Node) -> FilterResult,
184) -> Option<Node<'a>> {
185    let mut next = node;
186    let mut consider_children = false;
187    while let Some(current) = next {
188        if let Some(Some(child)) = consider_children.then(|| current.children().next()) {
189            let result = filter(&child);
190            next = Some(child);
191            if result == FilterResult::Include {
192                return next;
193            }
194            consider_children = result == FilterResult::ExcludeNode;
195        } else if let Some(sibling) = current.following_siblings().next() {
196            let result = filter(&sibling);
197            next = Some(sibling);
198            if result == FilterResult::Include {
199                return next;
200            }
201            if result == FilterResult::ExcludeNode {
202                consider_children = true;
203            }
204        } else {
205            let parent = current.parent();
206            next = parent;
207            if let Some(parent) = parent {
208                if filter(&parent) != FilterResult::ExcludeNode {
209                    return None;
210                }
211                consider_children = false;
212            } else {
213                return None;
214            }
215        }
216    }
217    None
218}
219
220fn previous_filtered_sibling<'a>(
221    node: Option<Node<'a>>,
222    filter: &impl Fn(&Node) -> FilterResult,
223) -> Option<Node<'a>> {
224    let mut previous = node;
225    let mut consider_children = false;
226    while let Some(current) = previous {
227        if let Some(Some(child)) = consider_children.then(|| current.children().next_back()) {
228            let result = filter(&child);
229            previous = Some(child);
230            if result == FilterResult::Include {
231                return previous;
232            }
233            consider_children = result == FilterResult::ExcludeNode;
234        } else if let Some(sibling) = current.preceding_siblings().next() {
235            let result = filter(&sibling);
236            previous = Some(sibling);
237            if result == FilterResult::Include {
238                return previous;
239            }
240            if result == FilterResult::ExcludeNode {
241                consider_children = true;
242            }
243        } else {
244            let parent = current.parent();
245            previous = parent;
246            if let Some(parent) = parent {
247                if filter(&parent) != FilterResult::ExcludeNode {
248                    return None;
249                }
250                consider_children = false;
251            } else {
252                return None;
253            }
254        }
255    }
256    None
257}
258
259/// An iterator that yields following siblings of a node according to the
260/// specified filter.
261///
262/// This struct is created by the [`following_filtered_siblings`](Node::following_filtered_siblings) method on [`Node`].
263pub struct FollowingFilteredSiblings<'a, Filter: Fn(&Node) -> FilterResult> {
264    filter: Filter,
265    back: Option<Node<'a>>,
266    done: bool,
267    front: Option<Node<'a>>,
268}
269
270impl<'a, Filter: Fn(&Node) -> FilterResult> FollowingFilteredSiblings<'a, Filter> {
271    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
272        let front = next_filtered_sibling(Some(node), &filter);
273        let back = node
274            .filtered_parent(&filter)
275            .and_then(|parent| parent.last_filtered_child(&filter));
276        Self {
277            filter,
278            back,
279            done: back.is_none() || front.is_none(),
280            front,
281        }
282    }
283}
284
285impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for FollowingFilteredSiblings<'a, Filter> {
286    type Item = Node<'a>;
287
288    fn next(&mut self) -> Option<Self::Item> {
289        if self.done {
290            None
291        } else {
292            self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id();
293            let current = self.front;
294            self.front = next_filtered_sibling(self.front, &self.filter);
295            current
296        }
297    }
298}
299
300impl<'a, Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
301    for FollowingFilteredSiblings<'a, Filter>
302{
303    fn next_back(&mut self) -> Option<Self::Item> {
304        if self.done {
305            None
306        } else {
307            self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id();
308            let current = self.back;
309            self.back = previous_filtered_sibling(self.back, &self.filter);
310            current
311        }
312    }
313}
314
315impl<'a, Filter: Fn(&Node) -> FilterResult> FusedIterator
316    for FollowingFilteredSiblings<'a, Filter>
317{
318}
319
320/// An iterator that yields preceding siblings of a node according to the
321/// specified filter.
322///
323/// This struct is created by the [`preceding_filtered_siblings`](Node::preceding_filtered_siblings) method on [`Node`].
324pub struct PrecedingFilteredSiblings<'a, Filter: Fn(&Node) -> FilterResult> {
325    filter: Filter,
326    back: Option<Node<'a>>,
327    done: bool,
328    front: Option<Node<'a>>,
329}
330
331impl<'a, Filter: Fn(&Node) -> FilterResult> PrecedingFilteredSiblings<'a, Filter> {
332    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
333        let front = previous_filtered_sibling(Some(node), &filter);
334        let back = node
335            .filtered_parent(&filter)
336            .and_then(|parent| parent.first_filtered_child(&filter));
337        Self {
338            filter,
339            back,
340            done: back.is_none() || front.is_none(),
341            front,
342        }
343    }
344}
345
346impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for PrecedingFilteredSiblings<'a, Filter> {
347    type Item = Node<'a>;
348
349    fn next(&mut self) -> Option<Self::Item> {
350        if self.done {
351            None
352        } else {
353            self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id();
354            let current = self.front;
355            self.front = previous_filtered_sibling(self.front, &self.filter);
356            current
357        }
358    }
359}
360
361impl<'a, Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
362    for PrecedingFilteredSiblings<'a, Filter>
363{
364    fn next_back(&mut self) -> Option<Self::Item> {
365        if self.done {
366            None
367        } else {
368            self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id();
369            let current = self.back;
370            self.back = next_filtered_sibling(self.back, &self.filter);
371            current
372        }
373    }
374}
375
376impl<'a, Filter: Fn(&Node) -> FilterResult> FusedIterator
377    for PrecedingFilteredSiblings<'a, Filter>
378{
379}
380
381/// An iterator that yields children of a node according to the specified
382/// filter.
383///
384/// This struct is created by the [`filtered_children`](Node::filtered_children) method on [`Node`].
385pub struct FilteredChildren<'a, Filter: Fn(&Node) -> FilterResult> {
386    filter: Filter,
387    back: Option<Node<'a>>,
388    done: bool,
389    front: Option<Node<'a>>,
390}
391
392impl<'a, Filter: Fn(&Node) -> FilterResult> FilteredChildren<'a, Filter> {
393    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
394        let front = node.first_filtered_child(&filter);
395        let back = node.last_filtered_child(&filter);
396        Self {
397            filter,
398            back,
399            done: back.is_none() || front.is_none(),
400            front,
401        }
402    }
403}
404
405impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for FilteredChildren<'a, Filter> {
406    type Item = Node<'a>;
407
408    fn next(&mut self) -> Option<Self::Item> {
409        if self.done {
410            None
411        } else {
412            self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id();
413            let current = self.front;
414            self.front = next_filtered_sibling(self.front, &self.filter);
415            current
416        }
417    }
418}
419
420impl<'a, Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for FilteredChildren<'a, Filter> {
421    fn next_back(&mut self) -> Option<Self::Item> {
422        if self.done {
423            None
424        } else {
425            self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id();
426            let current = self.back;
427            self.back = previous_filtered_sibling(self.back, &self.filter);
428            current
429        }
430    }
431}
432
433impl<'a, Filter: Fn(&Node) -> FilterResult> FusedIterator for FilteredChildren<'a, Filter> {}
434
435pub(crate) enum LabelledBy<'a, Filter: Fn(&Node) -> FilterResult> {
436    FromDescendants(FilteredChildren<'a, Filter>),
437    Explicit {
438        ids: std::slice::Iter<'a, NodeId>,
439        tree_state: &'a TreeState,
440    },
441}
442
443impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for LabelledBy<'a, Filter> {
444    type Item = Node<'a>;
445
446    fn next(&mut self) -> Option<Self::Item> {
447        match self {
448            Self::FromDescendants(iter) => iter.next(),
449            Self::Explicit { ids, tree_state } => {
450                ids.next().map(|id| tree_state.node_by_id(*id).unwrap())
451            }
452        }
453    }
454
455    fn size_hint(&self) -> (usize, Option<usize>) {
456        match self {
457            Self::FromDescendants(iter) => iter.size_hint(),
458            Self::Explicit { ids, .. } => ids.size_hint(),
459        }
460    }
461}
462
463impl<'a, Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for LabelledBy<'a, Filter> {
464    fn next_back(&mut self) -> Option<Self::Item> {
465        match self {
466            Self::FromDescendants(iter) => iter.next_back(),
467            Self::Explicit { ids, tree_state } => ids
468                .next_back()
469                .map(|id| tree_state.node_by_id(*id).unwrap()),
470        }
471    }
472}
473
474impl<'a, Filter: Fn(&Node) -> FilterResult> FusedIterator for LabelledBy<'a, Filter> {}
475
476#[cfg(test)]
477mod tests {
478    use crate::tests::*;
479    use accesskit::NodeId;
480
481    #[test]
482    fn following_siblings() {
483        let tree = test_tree();
484        assert!(tree.state().root().following_siblings().next().is_none());
485        assert_eq!(0, tree.state().root().following_siblings().len());
486        assert_eq!(
487            [
488                PARAGRAPH_1_IGNORED_ID,
489                PARAGRAPH_2_ID,
490                PARAGRAPH_3_IGNORED_ID
491            ],
492            tree.state()
493                .node_by_id(PARAGRAPH_0_ID)
494                .unwrap()
495                .following_siblings()
496                .map(|node| node.id())
497                .collect::<Vec<NodeId>>()[..]
498        );
499        assert_eq!(
500            3,
501            tree.state()
502                .node_by_id(PARAGRAPH_0_ID)
503                .unwrap()
504                .following_siblings()
505                .len()
506        );
507        assert!(tree
508            .state()
509            .node_by_id(PARAGRAPH_3_IGNORED_ID)
510            .unwrap()
511            .following_siblings()
512            .next()
513            .is_none());
514        assert_eq!(
515            0,
516            tree.state()
517                .node_by_id(PARAGRAPH_3_IGNORED_ID)
518                .unwrap()
519                .following_siblings()
520                .len()
521        );
522    }
523
524    #[test]
525    fn following_siblings_reversed() {
526        let tree = test_tree();
527        assert!(tree
528            .state()
529            .root()
530            .following_siblings()
531            .next_back()
532            .is_none());
533        assert_eq!(
534            [
535                PARAGRAPH_3_IGNORED_ID,
536                PARAGRAPH_2_ID,
537                PARAGRAPH_1_IGNORED_ID
538            ],
539            tree.state()
540                .node_by_id(PARAGRAPH_0_ID)
541                .unwrap()
542                .following_siblings()
543                .rev()
544                .map(|node| node.id())
545                .collect::<Vec<NodeId>>()[..]
546        );
547        assert!(tree
548            .state()
549            .node_by_id(PARAGRAPH_3_IGNORED_ID)
550            .unwrap()
551            .following_siblings()
552            .next_back()
553            .is_none());
554    }
555
556    #[test]
557    fn preceding_siblings() {
558        let tree = test_tree();
559        assert!(tree.state().root().preceding_siblings().next().is_none());
560        assert_eq!(0, tree.state().root().preceding_siblings().len());
561        assert_eq!(
562            [PARAGRAPH_2_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_0_ID],
563            tree.state()
564                .node_by_id(PARAGRAPH_3_IGNORED_ID)
565                .unwrap()
566                .preceding_siblings()
567                .map(|node| node.id())
568                .collect::<Vec<NodeId>>()[..]
569        );
570        assert_eq!(
571            3,
572            tree.state()
573                .node_by_id(PARAGRAPH_3_IGNORED_ID)
574                .unwrap()
575                .preceding_siblings()
576                .len()
577        );
578        assert!(tree
579            .state()
580            .node_by_id(PARAGRAPH_0_ID)
581            .unwrap()
582            .preceding_siblings()
583            .next()
584            .is_none());
585        assert_eq!(
586            0,
587            tree.state()
588                .node_by_id(PARAGRAPH_0_ID)
589                .unwrap()
590                .preceding_siblings()
591                .len()
592        );
593    }
594
595    #[test]
596    fn preceding_siblings_reversed() {
597        let tree = test_tree();
598        assert!(tree
599            .state()
600            .root()
601            .preceding_siblings()
602            .next_back()
603            .is_none());
604        assert_eq!(
605            [PARAGRAPH_0_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_2_ID],
606            tree.state()
607                .node_by_id(PARAGRAPH_3_IGNORED_ID)
608                .unwrap()
609                .preceding_siblings()
610                .rev()
611                .map(|node| node.id())
612                .collect::<Vec<NodeId>>()[..]
613        );
614        assert!(tree
615            .state()
616            .node_by_id(PARAGRAPH_0_ID)
617            .unwrap()
618            .preceding_siblings()
619            .next_back()
620            .is_none());
621    }
622
623    #[test]
624    fn following_filtered_siblings() {
625        let tree = test_tree();
626        assert!(tree
627            .state()
628            .root()
629            .following_filtered_siblings(test_tree_filter)
630            .next()
631            .is_none());
632        assert_eq!(
633            [LABEL_1_1_ID, PARAGRAPH_2_ID, LABEL_3_1_0_ID, BUTTON_3_2_ID],
634            tree.state()
635                .node_by_id(PARAGRAPH_0_ID)
636                .unwrap()
637                .following_filtered_siblings(test_tree_filter)
638                .map(|node| node.id())
639                .collect::<Vec<NodeId>>()[..]
640        );
641        assert_eq!(
642            [BUTTON_3_2_ID],
643            tree.state()
644                .node_by_id(LABEL_3_1_0_ID)
645                .unwrap()
646                .following_filtered_siblings(test_tree_filter)
647                .map(|node| node.id())
648                .collect::<Vec<NodeId>>()[..]
649        );
650        assert!(tree
651            .state()
652            .node_by_id(PARAGRAPH_3_IGNORED_ID)
653            .unwrap()
654            .following_filtered_siblings(test_tree_filter)
655            .next()
656            .is_none());
657    }
658
659    #[test]
660    fn following_filtered_siblings_reversed() {
661        let tree = test_tree();
662        assert!(tree
663            .state()
664            .root()
665            .following_filtered_siblings(test_tree_filter)
666            .next_back()
667            .is_none());
668        assert_eq!(
669            [BUTTON_3_2_ID, LABEL_3_1_0_ID, PARAGRAPH_2_ID, LABEL_1_1_ID],
670            tree.state()
671                .node_by_id(PARAGRAPH_0_ID)
672                .unwrap()
673                .following_filtered_siblings(test_tree_filter)
674                .rev()
675                .map(|node| node.id())
676                .collect::<Vec<NodeId>>()[..]
677        );
678        assert_eq!(
679            [BUTTON_3_2_ID,],
680            tree.state()
681                .node_by_id(LABEL_3_1_0_ID)
682                .unwrap()
683                .following_filtered_siblings(test_tree_filter)
684                .rev()
685                .map(|node| node.id())
686                .collect::<Vec<NodeId>>()[..]
687        );
688        assert!(tree
689            .state()
690            .node_by_id(PARAGRAPH_3_IGNORED_ID)
691            .unwrap()
692            .following_filtered_siblings(test_tree_filter)
693            .next_back()
694            .is_none());
695    }
696
697    #[test]
698    fn preceding_filtered_siblings() {
699        let tree = test_tree();
700        assert!(tree
701            .state()
702            .root()
703            .preceding_filtered_siblings(test_tree_filter)
704            .next()
705            .is_none());
706        assert_eq!(
707            [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
708            tree.state()
709                .node_by_id(PARAGRAPH_3_IGNORED_ID)
710                .unwrap()
711                .preceding_filtered_siblings(test_tree_filter)
712                .map(|node| node.id())
713                .collect::<Vec<NodeId>>()[..]
714        );
715        assert_eq!(
716            [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
717            tree.state()
718                .node_by_id(LABEL_3_1_0_ID)
719                .unwrap()
720                .preceding_filtered_siblings(test_tree_filter)
721                .map(|node| node.id())
722                .collect::<Vec<NodeId>>()[..]
723        );
724        assert!(tree
725            .state()
726            .node_by_id(PARAGRAPH_0_ID)
727            .unwrap()
728            .preceding_filtered_siblings(test_tree_filter)
729            .next()
730            .is_none());
731    }
732
733    #[test]
734    fn preceding_filtered_siblings_reversed() {
735        let tree = test_tree();
736        assert!(tree
737            .state()
738            .root()
739            .preceding_filtered_siblings(test_tree_filter)
740            .next_back()
741            .is_none());
742        assert_eq!(
743            [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
744            tree.state()
745                .node_by_id(PARAGRAPH_3_IGNORED_ID)
746                .unwrap()
747                .preceding_filtered_siblings(test_tree_filter)
748                .rev()
749                .map(|node| node.id())
750                .collect::<Vec<NodeId>>()[..]
751        );
752        assert_eq!(
753            [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
754            tree.state()
755                .node_by_id(LABEL_3_1_0_ID)
756                .unwrap()
757                .preceding_filtered_siblings(test_tree_filter)
758                .rev()
759                .map(|node| node.id())
760                .collect::<Vec<NodeId>>()[..]
761        );
762        assert!(tree
763            .state()
764            .node_by_id(PARAGRAPH_0_ID)
765            .unwrap()
766            .preceding_filtered_siblings(test_tree_filter)
767            .next_back()
768            .is_none());
769    }
770
771    #[test]
772    fn filtered_children() {
773        let tree = test_tree();
774        assert_eq!(
775            [
776                PARAGRAPH_0_ID,
777                LABEL_1_1_ID,
778                PARAGRAPH_2_ID,
779                LABEL_3_1_0_ID,
780                BUTTON_3_2_ID
781            ],
782            tree.state()
783                .root()
784                .filtered_children(test_tree_filter)
785                .map(|node| node.id())
786                .collect::<Vec<NodeId>>()[..]
787        );
788        assert!(tree
789            .state()
790            .node_by_id(PARAGRAPH_0_ID)
791            .unwrap()
792            .filtered_children(test_tree_filter)
793            .next()
794            .is_none());
795        assert!(tree
796            .state()
797            .node_by_id(LABEL_0_0_IGNORED_ID)
798            .unwrap()
799            .filtered_children(test_tree_filter)
800            .next()
801            .is_none());
802    }
803
804    #[test]
805    fn filtered_children_reversed() {
806        let tree = test_tree();
807        assert_eq!(
808            [
809                BUTTON_3_2_ID,
810                LABEL_3_1_0_ID,
811                PARAGRAPH_2_ID,
812                LABEL_1_1_ID,
813                PARAGRAPH_0_ID
814            ],
815            tree.state()
816                .root()
817                .filtered_children(test_tree_filter)
818                .rev()
819                .map(|node| node.id())
820                .collect::<Vec<NodeId>>()[..]
821        );
822        assert!(tree
823            .state()
824            .node_by_id(PARAGRAPH_0_ID)
825            .unwrap()
826            .filtered_children(test_tree_filter)
827            .next_back()
828            .is_none());
829        assert!(tree
830            .state()
831            .node_by_id(LABEL_0_0_IGNORED_ID)
832            .unwrap()
833            .filtered_children(test_tree_filter)
834            .next_back()
835            .is_none());
836    }
837}