1use core::iter::FusedIterator;
12
13use accesskit::NodeId;
14
15use crate::{filters::FilterResult, node::Node, tree::State as TreeState};
16
17pub 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 Iterator for FollowingSiblings<'_> {
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 DoubleEndedIterator for FollowingSiblings<'_> {
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 ExactSizeIterator for FollowingSiblings<'_> {}
98
99impl FusedIterator for FollowingSiblings<'_> {}
100
101pub 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 Iterator for PrecedingSiblings<'_> {
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 DoubleEndedIterator for PrecedingSiblings<'_> {
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 ExactSizeIterator for PrecedingSiblings<'_> {}
178
179impl FusedIterator for PrecedingSiblings<'_> {}
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
259pub 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
293 .front
294 .as_ref()
295 .zip(self.back.as_ref())
296 .map(|(f, b)| f.id() == b.id())
297 .unwrap_or(true);
298 let current = self.front;
299 self.front = next_filtered_sibling(self.front, &self.filter);
300 current
301 }
302 }
303}
304
305impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
306 for FollowingFilteredSiblings<'_, Filter>
307{
308 fn next_back(&mut self) -> Option<Self::Item> {
309 if self.done {
310 None
311 } else {
312 self.done = self
313 .front
314 .as_ref()
315 .zip(self.back.as_ref())
316 .map(|(f, b)| f.id() == b.id())
317 .unwrap_or(true);
318 let current = self.back;
319 self.back = previous_filtered_sibling(self.back, &self.filter);
320 current
321 }
322 }
323}
324
325impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for FollowingFilteredSiblings<'_, Filter> {}
326
327pub struct PrecedingFilteredSiblings<'a, Filter: Fn(&Node) -> FilterResult> {
332 filter: Filter,
333 back: Option<Node<'a>>,
334 done: bool,
335 front: Option<Node<'a>>,
336}
337
338impl<'a, Filter: Fn(&Node) -> FilterResult> PrecedingFilteredSiblings<'a, Filter> {
339 pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
340 let front = previous_filtered_sibling(Some(node), &filter);
341 let back = node
342 .filtered_parent(&filter)
343 .and_then(|parent| parent.first_filtered_child(&filter));
344 Self {
345 filter,
346 back,
347 done: back.is_none() || front.is_none(),
348 front,
349 }
350 }
351}
352
353impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for PrecedingFilteredSiblings<'a, Filter> {
354 type Item = Node<'a>;
355
356 fn next(&mut self) -> Option<Self::Item> {
357 if self.done {
358 None
359 } else {
360 self.done = self
361 .front
362 .as_ref()
363 .zip(self.back.as_ref())
364 .map(|(f, b)| f.id() == b.id())
365 .unwrap_or(true);
366 let current = self.front;
367 self.front = previous_filtered_sibling(self.front, &self.filter);
368 current
369 }
370 }
371}
372
373impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator
374 for PrecedingFilteredSiblings<'_, Filter>
375{
376 fn next_back(&mut self) -> Option<Self::Item> {
377 if self.done {
378 None
379 } else {
380 self.done = self
381 .front
382 .as_ref()
383 .zip(self.back.as_ref())
384 .map(|(f, b)| f.id() == b.id())
385 .unwrap_or(true);
386 let current = self.back;
387 self.back = next_filtered_sibling(self.back, &self.filter);
388 current
389 }
390 }
391}
392
393impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for PrecedingFilteredSiblings<'_, Filter> {}
394
395pub struct FilteredChildren<'a, Filter: Fn(&Node) -> FilterResult> {
400 filter: Filter,
401 back: Option<Node<'a>>,
402 done: bool,
403 front: Option<Node<'a>>,
404}
405
406impl<'a, Filter: Fn(&Node) -> FilterResult> FilteredChildren<'a, Filter> {
407 pub(crate) fn new(node: Node<'a>, filter: Filter) -> Self {
408 let front = node.first_filtered_child(&filter);
409 let back = node.last_filtered_child(&filter);
410 Self {
411 filter,
412 back,
413 done: back.is_none() || front.is_none(),
414 front,
415 }
416 }
417}
418
419impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for FilteredChildren<'a, Filter> {
420 type Item = Node<'a>;
421
422 fn next(&mut self) -> Option<Self::Item> {
423 if self.done {
424 None
425 } else {
426 self.done = self
427 .front
428 .as_ref()
429 .zip(self.back.as_ref())
430 .map(|(f, b)| f.id() == b.id())
431 .unwrap_or(true);
432 let current = self.front;
433 self.front = next_filtered_sibling(self.front, &self.filter);
434 current
435 }
436 }
437}
438
439impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for FilteredChildren<'_, Filter> {
440 fn next_back(&mut self) -> Option<Self::Item> {
441 if self.done {
442 None
443 } else {
444 self.done = self
445 .front
446 .as_ref()
447 .zip(self.back.as_ref())
448 .map(|(f, b)| f.id() == b.id())
449 .unwrap_or(true);
450 let current = self.back;
451 self.back = previous_filtered_sibling(self.back, &self.filter);
452 current
453 }
454 }
455}
456
457impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for FilteredChildren<'_, Filter> {}
458
459pub(crate) enum LabelledBy<'a, Filter: Fn(&Node) -> FilterResult> {
460 FromDescendants(FilteredChildren<'a, Filter>),
461 Explicit {
462 ids: core::slice::Iter<'a, NodeId>,
463 tree_state: &'a TreeState,
464 },
465}
466
467impl<'a, Filter: Fn(&Node) -> FilterResult> Iterator for LabelledBy<'a, Filter> {
468 type Item = Node<'a>;
469
470 fn next(&mut self) -> Option<Self::Item> {
471 match self {
472 Self::FromDescendants(iter) => iter.next(),
473 Self::Explicit { ids, tree_state } => {
474 ids.next().map(|id| tree_state.node_by_id(*id).unwrap())
475 }
476 }
477 }
478
479 fn size_hint(&self) -> (usize, Option<usize>) {
480 match self {
481 Self::FromDescendants(iter) => iter.size_hint(),
482 Self::Explicit { ids, .. } => ids.size_hint(),
483 }
484 }
485}
486
487impl<Filter: Fn(&Node) -> FilterResult> DoubleEndedIterator for LabelledBy<'_, Filter> {
488 fn next_back(&mut self) -> Option<Self::Item> {
489 match self {
490 Self::FromDescendants(iter) => iter.next_back(),
491 Self::Explicit { ids, tree_state } => ids
492 .next_back()
493 .map(|id| tree_state.node_by_id(*id).unwrap()),
494 }
495 }
496}
497
498impl<Filter: Fn(&Node) -> FilterResult> FusedIterator for LabelledBy<'_, Filter> {}
499
500#[cfg(test)]
501mod tests {
502 use crate::tests::*;
503 use accesskit::NodeId;
504 use alloc::vec::Vec;
505
506 #[test]
507 fn following_siblings() {
508 let tree = test_tree();
509 assert!(tree.state().root().following_siblings().next().is_none());
510 assert_eq!(0, tree.state().root().following_siblings().len());
511 assert_eq!(
512 [
513 PARAGRAPH_1_IGNORED_ID,
514 PARAGRAPH_2_ID,
515 PARAGRAPH_3_IGNORED_ID
516 ],
517 tree.state()
518 .node_by_id(PARAGRAPH_0_ID)
519 .unwrap()
520 .following_siblings()
521 .map(|node| node.id())
522 .collect::<Vec<NodeId>>()[..]
523 );
524 assert_eq!(
525 3,
526 tree.state()
527 .node_by_id(PARAGRAPH_0_ID)
528 .unwrap()
529 .following_siblings()
530 .len()
531 );
532 assert!(tree
533 .state()
534 .node_by_id(PARAGRAPH_3_IGNORED_ID)
535 .unwrap()
536 .following_siblings()
537 .next()
538 .is_none());
539 assert_eq!(
540 0,
541 tree.state()
542 .node_by_id(PARAGRAPH_3_IGNORED_ID)
543 .unwrap()
544 .following_siblings()
545 .len()
546 );
547 }
548
549 #[test]
550 fn following_siblings_reversed() {
551 let tree = test_tree();
552 assert!(tree
553 .state()
554 .root()
555 .following_siblings()
556 .next_back()
557 .is_none());
558 assert_eq!(
559 [
560 PARAGRAPH_3_IGNORED_ID,
561 PARAGRAPH_2_ID,
562 PARAGRAPH_1_IGNORED_ID
563 ],
564 tree.state()
565 .node_by_id(PARAGRAPH_0_ID)
566 .unwrap()
567 .following_siblings()
568 .rev()
569 .map(|node| node.id())
570 .collect::<Vec<NodeId>>()[..]
571 );
572 assert!(tree
573 .state()
574 .node_by_id(PARAGRAPH_3_IGNORED_ID)
575 .unwrap()
576 .following_siblings()
577 .next_back()
578 .is_none());
579 }
580
581 #[test]
582 fn preceding_siblings() {
583 let tree = test_tree();
584 assert!(tree.state().root().preceding_siblings().next().is_none());
585 assert_eq!(0, tree.state().root().preceding_siblings().len());
586 assert_eq!(
587 [PARAGRAPH_2_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_0_ID],
588 tree.state()
589 .node_by_id(PARAGRAPH_3_IGNORED_ID)
590 .unwrap()
591 .preceding_siblings()
592 .map(|node| node.id())
593 .collect::<Vec<NodeId>>()[..]
594 );
595 assert_eq!(
596 3,
597 tree.state()
598 .node_by_id(PARAGRAPH_3_IGNORED_ID)
599 .unwrap()
600 .preceding_siblings()
601 .len()
602 );
603 assert!(tree
604 .state()
605 .node_by_id(PARAGRAPH_0_ID)
606 .unwrap()
607 .preceding_siblings()
608 .next()
609 .is_none());
610 assert_eq!(
611 0,
612 tree.state()
613 .node_by_id(PARAGRAPH_0_ID)
614 .unwrap()
615 .preceding_siblings()
616 .len()
617 );
618 }
619
620 #[test]
621 fn preceding_siblings_reversed() {
622 let tree = test_tree();
623 assert!(tree
624 .state()
625 .root()
626 .preceding_siblings()
627 .next_back()
628 .is_none());
629 assert_eq!(
630 [PARAGRAPH_0_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_2_ID],
631 tree.state()
632 .node_by_id(PARAGRAPH_3_IGNORED_ID)
633 .unwrap()
634 .preceding_siblings()
635 .rev()
636 .map(|node| node.id())
637 .collect::<Vec<NodeId>>()[..]
638 );
639 assert!(tree
640 .state()
641 .node_by_id(PARAGRAPH_0_ID)
642 .unwrap()
643 .preceding_siblings()
644 .next_back()
645 .is_none());
646 }
647
648 #[test]
649 fn following_filtered_siblings() {
650 let tree = test_tree();
651 assert!(tree
652 .state()
653 .root()
654 .following_filtered_siblings(test_tree_filter)
655 .next()
656 .is_none());
657 assert_eq!(
658 [LABEL_1_1_ID, PARAGRAPH_2_ID, LABEL_3_1_0_ID, BUTTON_3_2_ID],
659 tree.state()
660 .node_by_id(PARAGRAPH_0_ID)
661 .unwrap()
662 .following_filtered_siblings(test_tree_filter)
663 .map(|node| node.id())
664 .collect::<Vec<NodeId>>()[..]
665 );
666 assert_eq!(
667 [BUTTON_3_2_ID],
668 tree.state()
669 .node_by_id(LABEL_3_1_0_ID)
670 .unwrap()
671 .following_filtered_siblings(test_tree_filter)
672 .map(|node| node.id())
673 .collect::<Vec<NodeId>>()[..]
674 );
675 assert!(tree
676 .state()
677 .node_by_id(PARAGRAPH_3_IGNORED_ID)
678 .unwrap()
679 .following_filtered_siblings(test_tree_filter)
680 .next()
681 .is_none());
682 }
683
684 #[test]
685 fn following_filtered_siblings_reversed() {
686 let tree = test_tree();
687 assert!(tree
688 .state()
689 .root()
690 .following_filtered_siblings(test_tree_filter)
691 .next_back()
692 .is_none());
693 assert_eq!(
694 [BUTTON_3_2_ID, LABEL_3_1_0_ID, PARAGRAPH_2_ID, LABEL_1_1_ID],
695 tree.state()
696 .node_by_id(PARAGRAPH_0_ID)
697 .unwrap()
698 .following_filtered_siblings(test_tree_filter)
699 .rev()
700 .map(|node| node.id())
701 .collect::<Vec<NodeId>>()[..]
702 );
703 assert_eq!(
704 [BUTTON_3_2_ID,],
705 tree.state()
706 .node_by_id(LABEL_3_1_0_ID)
707 .unwrap()
708 .following_filtered_siblings(test_tree_filter)
709 .rev()
710 .map(|node| node.id())
711 .collect::<Vec<NodeId>>()[..]
712 );
713 assert!(tree
714 .state()
715 .node_by_id(PARAGRAPH_3_IGNORED_ID)
716 .unwrap()
717 .following_filtered_siblings(test_tree_filter)
718 .next_back()
719 .is_none());
720 }
721
722 #[test]
723 fn preceding_filtered_siblings() {
724 let tree = test_tree();
725 assert!(tree
726 .state()
727 .root()
728 .preceding_filtered_siblings(test_tree_filter)
729 .next()
730 .is_none());
731 assert_eq!(
732 [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
733 tree.state()
734 .node_by_id(PARAGRAPH_3_IGNORED_ID)
735 .unwrap()
736 .preceding_filtered_siblings(test_tree_filter)
737 .map(|node| node.id())
738 .collect::<Vec<NodeId>>()[..]
739 );
740 assert_eq!(
741 [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
742 tree.state()
743 .node_by_id(LABEL_3_1_0_ID)
744 .unwrap()
745 .preceding_filtered_siblings(test_tree_filter)
746 .map(|node| node.id())
747 .collect::<Vec<NodeId>>()[..]
748 );
749 assert!(tree
750 .state()
751 .node_by_id(PARAGRAPH_0_ID)
752 .unwrap()
753 .preceding_filtered_siblings(test_tree_filter)
754 .next()
755 .is_none());
756 }
757
758 #[test]
759 fn preceding_filtered_siblings_reversed() {
760 let tree = test_tree();
761 assert!(tree
762 .state()
763 .root()
764 .preceding_filtered_siblings(test_tree_filter)
765 .next_back()
766 .is_none());
767 assert_eq!(
768 [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
769 tree.state()
770 .node_by_id(PARAGRAPH_3_IGNORED_ID)
771 .unwrap()
772 .preceding_filtered_siblings(test_tree_filter)
773 .rev()
774 .map(|node| node.id())
775 .collect::<Vec<NodeId>>()[..]
776 );
777 assert_eq!(
778 [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
779 tree.state()
780 .node_by_id(LABEL_3_1_0_ID)
781 .unwrap()
782 .preceding_filtered_siblings(test_tree_filter)
783 .rev()
784 .map(|node| node.id())
785 .collect::<Vec<NodeId>>()[..]
786 );
787 assert!(tree
788 .state()
789 .node_by_id(PARAGRAPH_0_ID)
790 .unwrap()
791 .preceding_filtered_siblings(test_tree_filter)
792 .next_back()
793 .is_none());
794 }
795
796 #[test]
797 fn filtered_children() {
798 let tree = test_tree();
799 assert_eq!(
800 [
801 PARAGRAPH_0_ID,
802 LABEL_1_1_ID,
803 PARAGRAPH_2_ID,
804 LABEL_3_1_0_ID,
805 BUTTON_3_2_ID
806 ],
807 tree.state()
808 .root()
809 .filtered_children(test_tree_filter)
810 .map(|node| node.id())
811 .collect::<Vec<NodeId>>()[..]
812 );
813 assert!(tree
814 .state()
815 .node_by_id(PARAGRAPH_0_ID)
816 .unwrap()
817 .filtered_children(test_tree_filter)
818 .next()
819 .is_none());
820 assert!(tree
821 .state()
822 .node_by_id(LABEL_0_0_IGNORED_ID)
823 .unwrap()
824 .filtered_children(test_tree_filter)
825 .next()
826 .is_none());
827 }
828
829 #[test]
830 fn filtered_children_reversed() {
831 let tree = test_tree();
832 assert_eq!(
833 [
834 BUTTON_3_2_ID,
835 LABEL_3_1_0_ID,
836 PARAGRAPH_2_ID,
837 LABEL_1_1_ID,
838 PARAGRAPH_0_ID
839 ],
840 tree.state()
841 .root()
842 .filtered_children(test_tree_filter)
843 .rev()
844 .map(|node| node.id())
845 .collect::<Vec<NodeId>>()[..]
846 );
847 assert!(tree
848 .state()
849 .node_by_id(PARAGRAPH_0_ID)
850 .unwrap()
851 .filtered_children(test_tree_filter)
852 .next_back()
853 .is_none());
854 assert!(tree
855 .state()
856 .node_by_id(LABEL_0_0_IGNORED_ID)
857 .unwrap()
858 .filtered_children(test_tree_filter)
859 .next_back()
860 .is_none());
861 }
862}