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 core::iter::FusedIterator;
12
13use accesskit::NodeId as LocalNodeId;
14
15use crate::{
16    filters::FilterResult,
17    node::{Node, NodeId},
18    tree::State as TreeState,
19};
20
21/// Iterator over child NodeIds, handling both normal nodes and graft nodes.
22pub enum ChildIds<'a> {
23    Normal {
24        parent_id: NodeId,
25        children: core::slice::Iter<'a, LocalNodeId>,
26    },
27    Graft(Option<NodeId>),
28}
29
30impl Iterator for ChildIds<'_> {
31    type Item = NodeId;
32
33    fn next(&mut self) -> Option<Self::Item> {
34        match self {
35            Self::Normal {
36                parent_id,
37                children,
38            } => children
39                .next()
40                .map(|child| parent_id.with_same_tree(*child)),
41            Self::Graft(id) => id.take(),
42        }
43    }
44
45    fn size_hint(&self) -> (usize, Option<usize>) {
46        let len = self.len();
47        (len, Some(len))
48    }
49}
50
51impl DoubleEndedIterator for ChildIds<'_> {
52    fn next_back(&mut self) -> Option<Self::Item> {
53        match self {
54            Self::Normal {
55                parent_id,
56                children,
57            } => children
58                .next_back()
59                .map(|child| parent_id.with_same_tree(*child)),
60            Self::Graft(id) => id.take(),
61        }
62    }
63}
64
65impl ExactSizeIterator for ChildIds<'_> {
66    fn len(&self) -> usize {
67        match self {
68            Self::Normal { children, .. } => children.len(),
69            Self::Graft(id) => usize::from(id.is_some()),
70        }
71    }
72}
73
74impl FusedIterator for ChildIds<'_> {}
75
76/// An iterator that yields following siblings of a node.
77///
78/// This struct is created by the [`following_siblings`](Node::following_siblings) method on [`Node`].
79pub struct FollowingSiblings<'a> {
80    back_position: usize,
81    done: bool,
82    front_position: usize,
83    parent: Option<Node<'a>>,
84    node_id: NodeId,
85}
86
87impl<'a> FollowingSiblings<'a> {
88    pub(crate) fn new(node: Node<'a>) -> Self {
89        let parent_and_index = node.parent_and_index();
90        let (back_position, front_position, done) =
91            if let Some((ref parent, index)) = parent_and_index {
92                // Graft nodes have only one child (the subtree root)
93                if parent.is_graft() {
94                    (0, 0, true)
95                } else {
96                    let back_position = parent.data().children().len() - 1;
97                    let front_position = index + 1;
98                    (
99                        back_position,
100                        front_position,
101                        front_position > back_position,
102                    )
103                }
104            } else {
105                (0, 0, true)
106            };
107        Self {
108            back_position,
109            done,
110            front_position,
111            parent: parent_and_index.map(|(parent, _)| parent),
112            node_id: node.id,
113        }
114    }
115}
116
117impl Iterator for FollowingSiblings<'_> {
118    type Item = NodeId;
119
120    fn next(&mut self) -> Option<Self::Item> {
121        if self.done {
122            None
123        } else {
124            self.done = self.front_position == self.back_position;
125            let child = self
126                .parent
127                .as_ref()?
128                .data()
129                .children()
130                .get(self.front_position)?;
131            self.front_position += 1;
132            Some(self.node_id.with_same_tree(*child))
133        }
134    }
135
136    fn size_hint(&self) -> (usize, Option<usize>) {
137        let len = match self.done {
138            true => 0,
139            _ => self.back_position + 1 - self.front_position,
140        };
141        (len, Some(len))
142    }
143}
144
145impl DoubleEndedIterator for FollowingSiblings<'_> {
146    fn next_back(&mut self) -> Option<Self::Item> {
147        if self.done {
148            None
149        } else {
150            self.done = self.back_position == self.front_position;
151            let child = self
152                .parent
153                .as_ref()?
154                .data()
155                .children()
156                .get(self.back_position)?;
157            self.back_position -= 1;
158            Some(self.node_id.with_same_tree(*child))
159        }
160    }
161}
162
163impl ExactSizeIterator for FollowingSiblings<'_> {}
164
165impl FusedIterator for FollowingSiblings<'_> {}
166
167/// An iterator that yields preceding siblings of a node.
168///
169/// This struct is created by the [`preceding_siblings`](Node::preceding_siblings) method on [`Node`].
170pub struct PrecedingSiblings<'a> {
171    back_position: usize,
172    done: bool,
173    front_position: usize,
174    parent: Option<Node<'a>>,
175    node_id: NodeId,
176}
177
178impl<'a> PrecedingSiblings<'a> {
179    pub(crate) fn new(node: Node<'a>) -> Self {
180        let parent_and_index = node.parent_and_index();
181        let (back_position, front_position, done) =
182            if let Some((ref parent, index)) = parent_and_index {
183                // Graft nodes have only one child (the subtree root)
184                if parent.is_graft() {
185                    (0, 0, true)
186                } else {
187                    let front_position = index.saturating_sub(1);
188                    (0, front_position, index == 0)
189                }
190            } else {
191                (0, 0, true)
192            };
193        Self {
194            back_position,
195            done,
196            front_position,
197            parent: parent_and_index.map(|(parent, _)| parent),
198            node_id: node.id,
199        }
200    }
201}
202
203impl Iterator for PrecedingSiblings<'_> {
204    type Item = NodeId;
205
206    fn next(&mut self) -> Option<Self::Item> {
207        if self.done {
208            None
209        } else {
210            self.done = self.front_position == self.back_position;
211            let child = self
212                .parent
213                .as_ref()?
214                .data()
215                .children()
216                .get(self.front_position)?;
217            if !self.done {
218                self.front_position -= 1;
219            }
220            Some(self.node_id.with_same_tree(*child))
221        }
222    }
223
224    fn size_hint(&self) -> (usize, Option<usize>) {
225        let len = match self.done {
226            true => 0,
227            _ => self.front_position + 1 - self.back_position,
228        };
229        (len, Some(len))
230    }
231}
232
233impl DoubleEndedIterator for PrecedingSiblings<'_> {
234    fn next_back(&mut self) -> Option<Self::Item> {
235        if self.done {
236            None
237        } else {
238            self.done = self.back_position == self.front_position;
239            let child = self
240                .parent
241                .as_ref()?
242                .data()
243                .children()
244                .get(self.back_position)?;
245            self.back_position += 1;
246            Some(self.node_id.with_same_tree(*child))
247        }
248    }
249}
250
251impl ExactSizeIterator for PrecedingSiblings<'_> {}
252
253impl FusedIterator for PrecedingSiblings<'_> {}
254
255fn next_filtered_sibling<'a>(
256    node: Option<Node<'a>>,
257    filter: &impl Fn(&Node) -> FilterResult,
258) -> Option<Node<'a>> {
259    let mut next = node;
260    let mut consider_children = false;
261    while let Some(current) = next {
262        if let Some(Some(child)) = consider_children.then(|| current.children().next()) {
263            let result = filter(&child);
264            next = Some(child);
265            if result == FilterResult::Include {
266                return next;
267            }
268            consider_children = result == FilterResult::ExcludeNode;
269        } else if let Some(sibling) = current.following_siblings().next() {
270            let result = filter(&sibling);
271            next = Some(sibling);
272            if result == FilterResult::Include {
273                return next;
274            }
275            if result == FilterResult::ExcludeNode {
276                consider_children = true;
277            }
278        } else {
279            let parent = current.parent();
280            next = parent;
281            if let Some(parent) = parent {
282                if filter(&parent) != FilterResult::ExcludeNode {
283                    return None;
284                }
285                consider_children = false;
286            } else {
287                return None;
288            }
289        }
290    }
291    None
292}
293
294fn previous_filtered_sibling<'a>(
295    node: Option<Node<'a>>,
296    filter: &impl Fn(&Node) -> FilterResult,
297) -> Option<Node<'a>> {
298    let mut previous = node;
299    let mut consider_children = false;
300    while let Some(current) = previous {
301        if let Some(Some(child)) = consider_children.then(|| current.children().next_back()) {
302            let result = filter(&child);
303            previous = Some(child);
304            if result == FilterResult::Include {
305                return previous;
306            }
307            consider_children = result == FilterResult::ExcludeNode;
308        } else if let Some(sibling) = current.preceding_siblings().next() {
309            let result = filter(&sibling);
310            previous = Some(sibling);
311            if result == FilterResult::Include {
312                return previous;
313            }
314            if result == FilterResult::ExcludeNode {
315                consider_children = true;
316            }
317        } else {
318            let parent = current.parent();
319            previous = parent;
320            if let Some(parent) = parent {
321                if filter(&parent) != FilterResult::ExcludeNode {
322                    return None;
323                }
324                consider_children = false;
325            } else {
326                return None;
327            }
328        }
329    }
330    None
331}
332
333/// An iterator that yields following siblings of a node according to the
334/// specified filter.
335///
336/// This struct is created by the [`following_filtered_siblings`](Node::following_filtered_siblings) method on [`Node`].
337pub struct FollowingFilteredSiblings<'a, Filter: Fn(&Node) -> FilterResult> {
338    filter: Filter,
339    back: Option<Node<'a>>,
340    done: bool,
341    front: Option<Node<'a>>,
342}
343
344impl<'a, Filter: Fn(&Node) -> FilterResult> FollowingFilteredSiblings<'a, Filter> {
345    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
346        let front = next_filtered_sibling(Some(node), &filter);
347        let back = node
348            .filtered_parent(&filter)
349            .and_then(|parent| parent.last_filtered_child(&filter));
350        Self {
351            filter,
352            back,
353            done: back.is_none() || front.is_none(),
354            front,
355        }
356    }
357}
358
359impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for FollowingFilteredSiblings<'a, Filter> {
360    type Item = Node<'a>;
361
362    fn next(&mut self) -> Option<Self::Item> {
363        if self.done {
364            None
365        } else {
366            self.done = self
367                .front
368                .as_ref()
369                .zip(self.back.as_ref())
370                .map(|(f, b)| f.id() == b.id())
371                .unwrap_or(true);
372            let current = self.front;
373            self.front = next_filtered_sibling(self.front, &self.filter);
374            current
375        }
376    }
377}
378
379impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
380    for FollowingFilteredSiblings<'_, Filter>
381{
382    fn next_back(&mut self) -> Option<Self::Item> {
383        if self.done {
384            None
385        } else {
386            self.done = self
387                .front
388                .as_ref()
389                .zip(self.back.as_ref())
390                .map(|(f, b)| f.id() == b.id())
391                .unwrap_or(true);
392            let current = self.back;
393            self.back = previous_filtered_sibling(self.back, &self.filter);
394            current
395        }
396    }
397}
398
399impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for FollowingFilteredSiblings<'_, Filter> {}
400
401/// An iterator that yields preceding siblings of a node according to the
402/// specified filter.
403///
404/// This struct is created by the [`preceding_filtered_siblings`](Node::preceding_filtered_siblings) method on [`Node`].
405pub struct PrecedingFilteredSiblings<'a, Filter: Fn(&Node) -> FilterResult> {
406    filter: Filter,
407    back: Option<Node<'a>>,
408    done: bool,
409    front: Option<Node<'a>>,
410}
411
412impl<'a, Filter: Fn(&Node) -> FilterResult> PrecedingFilteredSiblings<'a, Filter> {
413    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
414        let front = previous_filtered_sibling(Some(node), &filter);
415        let back = node
416            .filtered_parent(&filter)
417            .and_then(|parent| parent.first_filtered_child(&filter));
418        Self {
419            filter,
420            back,
421            done: back.is_none() || front.is_none(),
422            front,
423        }
424    }
425}
426
427impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for PrecedingFilteredSiblings<'a, Filter> {
428    type Item = Node<'a>;
429
430    fn next(&mut self) -> Option<Self::Item> {
431        if self.done {
432            None
433        } else {
434            self.done = self
435                .front
436                .as_ref()
437                .zip(self.back.as_ref())
438                .map(|(f, b)| f.id() == b.id())
439                .unwrap_or(true);
440            let current = self.front;
441            self.front = previous_filtered_sibling(self.front, &self.filter);
442            current
443        }
444    }
445}
446
447impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
448    for PrecedingFilteredSiblings<'_, Filter>
449{
450    fn next_back(&mut self) -> Option<Self::Item> {
451        if self.done {
452            None
453        } else {
454            self.done = self
455                .front
456                .as_ref()
457                .zip(self.back.as_ref())
458                .map(|(f, b)| f.id() == b.id())
459                .unwrap_or(true);
460            let current = self.back;
461            self.back = next_filtered_sibling(self.back, &self.filter);
462            current
463        }
464    }
465}
466
467impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for PrecedingFilteredSiblings<'_, Filter> {}
468
469/// An iterator that yields children of a node according to the specified
470/// filter.
471///
472/// This struct is created by the [`filtered_children`](Node::filtered_children) method on [`Node`].
473pub struct FilteredChildren<'a, Filter: Fn(&Node) -> FilterResult> {
474    filter: Filter,
475    back: Option<Node<'a>>,
476    done: bool,
477    front: Option<Node<'a>>,
478}
479
480impl<'a, Filter: Fn(&Node) -> FilterResult> FilteredChildren<'a, Filter> {
481    pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
482        let front = node.first_filtered_child(&filter);
483        let back = node.last_filtered_child(&filter);
484        Self {
485            filter,
486            back,
487            done: back.is_none() || front.is_none(),
488            front,
489        }
490    }
491}
492
493impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for FilteredChildren<'a, Filter> {
494    type Item = Node<'a>;
495
496    fn next(&mut self) -> Option<Self::Item> {
497        if self.done {
498            None
499        } else {
500            self.done = self
501                .front
502                .as_ref()
503                .zip(self.back.as_ref())
504                .map(|(f, b)| f.id() == b.id())
505                .unwrap_or(true);
506            let current = self.front;
507            self.front = next_filtered_sibling(self.front, &self.filter);
508            current
509        }
510    }
511}
512
513impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for FilteredChildren<'_, Filter> {
514    fn next_back(&mut self) -> Option<Self::Item> {
515        if self.done {
516            None
517        } else {
518            self.done = self
519                .front
520                .as_ref()
521                .zip(self.back.as_ref())
522                .map(|(f, b)| f.id() == b.id())
523                .unwrap_or(true);
524            let current = self.back;
525            self.back = previous_filtered_sibling(self.back, &self.filter);
526            current
527        }
528    }
529}
530
531impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for FilteredChildren<'_, Filter> {}
532
533pub(crate) enum LabelledBy<'a, Filter: Fn(&Node) -> FilterResult> {
534    FromDescendants(FilteredChildren<'a, Filter>),
535    Explicit {
536        ids: core::slice::Iter<'a, LocalNodeId>,
537        tree_state: &'a TreeState,
538        node_id: NodeId,
539    },
540}
541
542impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for LabelledBy<'a, Filter> {
543    type Item = Node<'a>;
544
545    fn next(&mut self) -> Option<Self::Item> {
546        match self {
547            Self::FromDescendants(iter) => iter.next(),
548            Self::Explicit {
549                ids,
550                tree_state,
551                node_id,
552            } => ids
553                .next()
554                .map(|id| tree_state.node_by_id(node_id.with_same_tree(*id)).unwrap()),
555        }
556    }
557
558    fn size_hint(&self) -> (usize, Option<usize>) {
559        match self {
560            Self::FromDescendants(iter) => iter.size_hint(),
561            Self::Explicit { ids, .. } => ids.size_hint(),
562        }
563    }
564}
565
566impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for LabelledBy<'_, Filter> {
567    fn next_back(&mut self) -> Option<Self::Item> {
568        match self {
569            Self::FromDescendants(iter) => iter.next_back(),
570            Self::Explicit {
571                ids,
572                tree_state,
573                node_id,
574            } => ids
575                .next_back()
576                .map(|id| tree_state.node_by_id(node_id.with_same_tree(*id)).unwrap()),
577        }
578    }
579}
580
581impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for LabelledBy<'_, Filter> {}
582
583#[cfg(test)]
584mod tests {
585    use crate::{
586        filters::common_filter,
587        tests::*,
588        tree::{ChangeHandler, TreeIndex},
589        NodeId,
590    };
591    use accesskit::{Node, NodeId as LocalNodeId, Role, Tree, TreeId, TreeUpdate, Uuid};
592    use alloc::{vec, vec::Vec};
593
594    #[test]
595    fn following_siblings() {
596        let tree = test_tree();
597        assert!(tree.state().root().following_siblings().next().is_none());
598        assert_eq!(0, tree.state().root().following_siblings().len());
599        assert_eq!(
600            [
601                PARAGRAPH_1_IGNORED_ID,
602                PARAGRAPH_2_ID,
603                PARAGRAPH_3_IGNORED_ID
604            ],
605            tree.state()
606                .node_by_id(nid(PARAGRAPH_0_ID))
607                .unwrap()
608                .following_sibling_ids()
609                .map(|id| id.to_components().0)
610                .collect::<Vec<LocalNodeId>>()[..]
611        );
612        assert_eq!(
613            3,
614            tree.state()
615                .node_by_id(nid(PARAGRAPH_0_ID))
616                .unwrap()
617                .following_siblings()
618                .len()
619        );
620        assert!(tree
621            .state()
622            .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
623            .unwrap()
624            .following_siblings()
625            .next()
626            .is_none());
627        assert_eq!(
628            0,
629            tree.state()
630                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
631                .unwrap()
632                .following_siblings()
633                .len()
634        );
635    }
636
637    #[test]
638    fn following_siblings_reversed() {
639        let tree = test_tree();
640        assert!(tree
641            .state()
642            .root()
643            .following_siblings()
644            .next_back()
645            .is_none());
646        assert_eq!(
647            [
648                PARAGRAPH_3_IGNORED_ID,
649                PARAGRAPH_2_ID,
650                PARAGRAPH_1_IGNORED_ID
651            ],
652            tree.state()
653                .node_by_id(nid(PARAGRAPH_0_ID))
654                .unwrap()
655                .following_sibling_ids()
656                .rev()
657                .map(|id| id.to_components().0)
658                .collect::<Vec<LocalNodeId>>()[..]
659        );
660        assert!(tree
661            .state()
662            .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
663            .unwrap()
664            .following_siblings()
665            .next_back()
666            .is_none());
667    }
668
669    #[test]
670    fn preceding_siblings() {
671        let tree = test_tree();
672        assert!(tree.state().root().preceding_siblings().next().is_none());
673        assert_eq!(0, tree.state().root().preceding_siblings().len());
674        assert_eq!(
675            [PARAGRAPH_2_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_0_ID],
676            tree.state()
677                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
678                .unwrap()
679                .preceding_sibling_ids()
680                .map(|id| id.to_components().0)
681                .collect::<Vec<LocalNodeId>>()[..]
682        );
683        assert_eq!(
684            3,
685            tree.state()
686                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
687                .unwrap()
688                .preceding_siblings()
689                .len()
690        );
691        assert!(tree
692            .state()
693            .node_by_id(nid(PARAGRAPH_0_ID))
694            .unwrap()
695            .preceding_siblings()
696            .next()
697            .is_none());
698        assert_eq!(
699            0,
700            tree.state()
701                .node_by_id(nid(PARAGRAPH_0_ID))
702                .unwrap()
703                .preceding_siblings()
704                .len()
705        );
706    }
707
708    #[test]
709    fn preceding_siblings_reversed() {
710        let tree = test_tree();
711        assert!(tree
712            .state()
713            .root()
714            .preceding_siblings()
715            .next_back()
716            .is_none());
717        assert_eq!(
718            [PARAGRAPH_0_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_2_ID],
719            tree.state()
720                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
721                .unwrap()
722                .preceding_sibling_ids()
723                .rev()
724                .map(|id| id.to_components().0)
725                .collect::<Vec<LocalNodeId>>()[..]
726        );
727        assert!(tree
728            .state()
729            .node_by_id(nid(PARAGRAPH_0_ID))
730            .unwrap()
731            .preceding_siblings()
732            .next_back()
733            .is_none());
734    }
735
736    #[test]
737    fn following_filtered_siblings() {
738        let tree = test_tree();
739        assert!(tree
740            .state()
741            .root()
742            .following_filtered_siblings(test_tree_filter)
743            .next()
744            .is_none());
745        assert_eq!(
746            [LABEL_1_1_ID, PARAGRAPH_2_ID, LABEL_3_1_0_ID, BUTTON_3_2_ID],
747            tree.state()
748                .node_by_id(nid(PARAGRAPH_0_ID))
749                .unwrap()
750                .following_filtered_siblings(test_tree_filter)
751                .map(|node| node.id().to_components().0)
752                .collect::<Vec<LocalNodeId>>()[..]
753        );
754        assert_eq!(
755            [BUTTON_3_2_ID],
756            tree.state()
757                .node_by_id(nid(LABEL_3_1_0_ID))
758                .unwrap()
759                .following_filtered_siblings(test_tree_filter)
760                .map(|node| node.id().to_components().0)
761                .collect::<Vec<LocalNodeId>>()[..]
762        );
763        assert!(tree
764            .state()
765            .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
766            .unwrap()
767            .following_filtered_siblings(test_tree_filter)
768            .next()
769            .is_none());
770    }
771
772    #[test]
773    fn following_filtered_siblings_reversed() {
774        let tree = test_tree();
775        assert!(tree
776            .state()
777            .root()
778            .following_filtered_siblings(test_tree_filter)
779            .next_back()
780            .is_none());
781        assert_eq!(
782            [BUTTON_3_2_ID, LABEL_3_1_0_ID, PARAGRAPH_2_ID, LABEL_1_1_ID],
783            tree.state()
784                .node_by_id(nid(PARAGRAPH_0_ID))
785                .unwrap()
786                .following_filtered_siblings(test_tree_filter)
787                .rev()
788                .map(|node| node.id().to_components().0)
789                .collect::<Vec<LocalNodeId>>()[..]
790        );
791        assert_eq!(
792            [BUTTON_3_2_ID,],
793            tree.state()
794                .node_by_id(nid(LABEL_3_1_0_ID))
795                .unwrap()
796                .following_filtered_siblings(test_tree_filter)
797                .rev()
798                .map(|node| node.id().to_components().0)
799                .collect::<Vec<LocalNodeId>>()[..]
800        );
801        assert!(tree
802            .state()
803            .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
804            .unwrap()
805            .following_filtered_siblings(test_tree_filter)
806            .next_back()
807            .is_none());
808    }
809
810    #[test]
811    fn preceding_filtered_siblings() {
812        let tree = test_tree();
813        assert!(tree
814            .state()
815            .root()
816            .preceding_filtered_siblings(test_tree_filter)
817            .next()
818            .is_none());
819        assert_eq!(
820            [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
821            tree.state()
822                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
823                .unwrap()
824                .preceding_filtered_siblings(test_tree_filter)
825                .map(|node| node.id().to_components().0)
826                .collect::<Vec<LocalNodeId>>()[..]
827        );
828        assert_eq!(
829            [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
830            tree.state()
831                .node_by_id(nid(LABEL_3_1_0_ID))
832                .unwrap()
833                .preceding_filtered_siblings(test_tree_filter)
834                .map(|node| node.id().to_components().0)
835                .collect::<Vec<LocalNodeId>>()[..]
836        );
837        assert!(tree
838            .state()
839            .node_by_id(nid(PARAGRAPH_0_ID))
840            .unwrap()
841            .preceding_filtered_siblings(test_tree_filter)
842            .next()
843            .is_none());
844    }
845
846    #[test]
847    fn preceding_filtered_siblings_reversed() {
848        let tree = test_tree();
849        assert!(tree
850            .state()
851            .root()
852            .preceding_filtered_siblings(test_tree_filter)
853            .next_back()
854            .is_none());
855        assert_eq!(
856            [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
857            tree.state()
858                .node_by_id(nid(PARAGRAPH_3_IGNORED_ID))
859                .unwrap()
860                .preceding_filtered_siblings(test_tree_filter)
861                .rev()
862                .map(|node| node.id().to_components().0)
863                .collect::<Vec<LocalNodeId>>()[..]
864        );
865        assert_eq!(
866            [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
867            tree.state()
868                .node_by_id(nid(LABEL_3_1_0_ID))
869                .unwrap()
870                .preceding_filtered_siblings(test_tree_filter)
871                .rev()
872                .map(|node| node.id().to_components().0)
873                .collect::<Vec<LocalNodeId>>()[..]
874        );
875        assert!(tree
876            .state()
877            .node_by_id(nid(PARAGRAPH_0_ID))
878            .unwrap()
879            .preceding_filtered_siblings(test_tree_filter)
880            .next_back()
881            .is_none());
882    }
883
884    #[test]
885    fn filtered_children() {
886        let tree = test_tree();
887        assert_eq!(
888            [
889                PARAGRAPH_0_ID,
890                LABEL_1_1_ID,
891                PARAGRAPH_2_ID,
892                LABEL_3_1_0_ID,
893                BUTTON_3_2_ID
894            ],
895            tree.state()
896                .root()
897                .filtered_children(test_tree_filter)
898                .map(|node| node.id().to_components().0)
899                .collect::<Vec<LocalNodeId>>()[..]
900        );
901        assert!(tree
902            .state()
903            .node_by_id(nid(PARAGRAPH_0_ID))
904            .unwrap()
905            .filtered_children(test_tree_filter)
906            .next()
907            .is_none());
908        assert!(tree
909            .state()
910            .node_by_id(nid(LABEL_0_0_IGNORED_ID))
911            .unwrap()
912            .filtered_children(test_tree_filter)
913            .next()
914            .is_none());
915    }
916
917    #[test]
918    fn filtered_children_reversed() {
919        let tree = test_tree();
920        assert_eq!(
921            [
922                BUTTON_3_2_ID,
923                LABEL_3_1_0_ID,
924                PARAGRAPH_2_ID,
925                LABEL_1_1_ID,
926                PARAGRAPH_0_ID
927            ],
928            tree.state()
929                .root()
930                .filtered_children(test_tree_filter)
931                .rev()
932                .map(|node| node.id().to_components().0)
933                .collect::<Vec<LocalNodeId>>()[..]
934        );
935        assert!(tree
936            .state()
937            .node_by_id(nid(PARAGRAPH_0_ID))
938            .unwrap()
939            .filtered_children(test_tree_filter)
940            .next_back()
941            .is_none());
942        assert!(tree
943            .state()
944            .node_by_id(nid(LABEL_0_0_IGNORED_ID))
945            .unwrap()
946            .filtered_children(test_tree_filter)
947            .next_back()
948            .is_none());
949    }
950
951    #[test]
952    fn graft_node_without_subtree_has_no_filtered_children() {
953        let subtree_id = TreeId(Uuid::from_u128(1));
954
955        let update = TreeUpdate {
956            nodes: vec![
957                (LocalNodeId(0), {
958                    let mut node = Node::new(Role::Window);
959                    node.set_children(vec![LocalNodeId(1)]);
960                    node
961                }),
962                (LocalNodeId(1), {
963                    let mut node = Node::new(Role::GenericContainer);
964                    node.set_tree_id(subtree_id);
965                    node
966                }),
967            ],
968            tree: Some(Tree::new(LocalNodeId(0))),
969            tree_id: TreeId::ROOT,
970            focus: LocalNodeId(0),
971        };
972        let tree = crate::Tree::new(update, false);
973
974        let graft_node_id = NodeId::new(LocalNodeId(1), TreeIndex(0));
975        let graft_node = tree.state().node_by_id(graft_node_id).unwrap();
976        assert!(graft_node.filtered_children(common_filter).next().is_none());
977    }
978
979    #[test]
980    fn filtered_children_crosses_subtree_boundary() {
981        struct NoOpHandler;
982        impl ChangeHandler for NoOpHandler {
983            fn node_added(&mut self, _: &crate::Node) {}
984            fn node_updated(&mut self, _: &crate::Node, _: &crate::Node) {}
985            fn focus_moved(&mut self, _: Option<&crate::Node>, _: Option<&crate::Node>) {}
986            fn node_removed(&mut self, _: &crate::Node) {}
987        }
988
989        let subtree_id = TreeId(Uuid::from_u128(1));
990
991        let update = TreeUpdate {
992            nodes: vec![
993                (LocalNodeId(0), {
994                    let mut node = Node::new(Role::Window);
995                    node.set_children(vec![LocalNodeId(1)]);
996                    node
997                }),
998                (LocalNodeId(1), {
999                    let mut node = Node::new(Role::GenericContainer);
1000                    node.set_tree_id(subtree_id);
1001                    node
1002                }),
1003            ],
1004            tree: Some(Tree::new(LocalNodeId(0))),
1005            tree_id: TreeId::ROOT,
1006            focus: LocalNodeId(0),
1007        };
1008        let mut tree = crate::Tree::new(update, false);
1009
1010        let subtree_update = TreeUpdate {
1011            nodes: vec![
1012                (LocalNodeId(0), {
1013                    let mut node = Node::new(Role::Document);
1014                    node.set_children(vec![LocalNodeId(1)]);
1015                    node
1016                }),
1017                (LocalNodeId(1), Node::new(Role::Button)),
1018            ],
1019            tree: Some(Tree::new(LocalNodeId(0))),
1020            tree_id: subtree_id,
1021            focus: LocalNodeId(0),
1022        };
1023        tree.update_and_process_changes(subtree_update, &mut NoOpHandler);
1024
1025        let root = tree.state().root();
1026        let filtered_children: Vec<_> = root.filtered_children(common_filter).collect();
1027
1028        assert_eq!(1, filtered_children.len());
1029        let subtree_root_id = NodeId::new(LocalNodeId(0), TreeIndex(1));
1030        assert_eq!(subtree_root_id, filtered_children[0].id());
1031
1032        let document = &filtered_children[0];
1033        let doc_children: Vec<_> = document.filtered_children(common_filter).collect();
1034        assert_eq!(1, doc_children.len());
1035        let button_id = NodeId::new(LocalNodeId(1), TreeIndex(1));
1036        assert_eq!(button_id, doc_children[0].id());
1037    }
1038}