1use 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
21pub 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
76pub 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 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
167pub 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 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
333pub 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
401pub 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
469pub 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}