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<'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
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<'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
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.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
320pub 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
381pub 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: core::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 use alloc::vec::Vec;
481
482 #[test]
483 fn following_siblings() {
484 let tree = test_tree();
485 assert!(tree.state().root().following_siblings().next().is_none());
486 assert_eq!(0, tree.state().root().following_siblings().len());
487 assert_eq!(
488 [
489 PARAGRAPH_1_IGNORED_ID,
490 PARAGRAPH_2_ID,
491 PARAGRAPH_3_IGNORED_ID
492 ],
493 tree.state()
494 .node_by_id(PARAGRAPH_0_ID)
495 .unwrap()
496 .following_siblings()
497 .map(|node| node.id())
498 .collect::<Vec<NodeId>>()[..]
499 );
500 assert_eq!(
501 3,
502 tree.state()
503 .node_by_id(PARAGRAPH_0_ID)
504 .unwrap()
505 .following_siblings()
506 .len()
507 );
508 assert!(tree
509 .state()
510 .node_by_id(PARAGRAPH_3_IGNORED_ID)
511 .unwrap()
512 .following_siblings()
513 .next()
514 .is_none());
515 assert_eq!(
516 0,
517 tree.state()
518 .node_by_id(PARAGRAPH_3_IGNORED_ID)
519 .unwrap()
520 .following_siblings()
521 .len()
522 );
523 }
524
525 #[test]
526 fn following_siblings_reversed() {
527 let tree = test_tree();
528 assert!(tree
529 .state()
530 .root()
531 .following_siblings()
532 .next_back()
533 .is_none());
534 assert_eq!(
535 [
536 PARAGRAPH_3_IGNORED_ID,
537 PARAGRAPH_2_ID,
538 PARAGRAPH_1_IGNORED_ID
539 ],
540 tree.state()
541 .node_by_id(PARAGRAPH_0_ID)
542 .unwrap()
543 .following_siblings()
544 .rev()
545 .map(|node| node.id())
546 .collect::<Vec<NodeId>>()[..]
547 );
548 assert!(tree
549 .state()
550 .node_by_id(PARAGRAPH_3_IGNORED_ID)
551 .unwrap()
552 .following_siblings()
553 .next_back()
554 .is_none());
555 }
556
557 #[test]
558 fn preceding_siblings() {
559 let tree = test_tree();
560 assert!(tree.state().root().preceding_siblings().next().is_none());
561 assert_eq!(0, tree.state().root().preceding_siblings().len());
562 assert_eq!(
563 [PARAGRAPH_2_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_0_ID],
564 tree.state()
565 .node_by_id(PARAGRAPH_3_IGNORED_ID)
566 .unwrap()
567 .preceding_siblings()
568 .map(|node| node.id())
569 .collect::<Vec<NodeId>>()[..]
570 );
571 assert_eq!(
572 3,
573 tree.state()
574 .node_by_id(PARAGRAPH_3_IGNORED_ID)
575 .unwrap()
576 .preceding_siblings()
577 .len()
578 );
579 assert!(tree
580 .state()
581 .node_by_id(PARAGRAPH_0_ID)
582 .unwrap()
583 .preceding_siblings()
584 .next()
585 .is_none());
586 assert_eq!(
587 0,
588 tree.state()
589 .node_by_id(PARAGRAPH_0_ID)
590 .unwrap()
591 .preceding_siblings()
592 .len()
593 );
594 }
595
596 #[test]
597 fn preceding_siblings_reversed() {
598 let tree = test_tree();
599 assert!(tree
600 .state()
601 .root()
602 .preceding_siblings()
603 .next_back()
604 .is_none());
605 assert_eq!(
606 [PARAGRAPH_0_ID, PARAGRAPH_1_IGNORED_ID, PARAGRAPH_2_ID],
607 tree.state()
608 .node_by_id(PARAGRAPH_3_IGNORED_ID)
609 .unwrap()
610 .preceding_siblings()
611 .rev()
612 .map(|node| node.id())
613 .collect::<Vec<NodeId>>()[..]
614 );
615 assert!(tree
616 .state()
617 .node_by_id(PARAGRAPH_0_ID)
618 .unwrap()
619 .preceding_siblings()
620 .next_back()
621 .is_none());
622 }
623
624 #[test]
625 fn following_filtered_siblings() {
626 let tree = test_tree();
627 assert!(tree
628 .state()
629 .root()
630 .following_filtered_siblings(test_tree_filter)
631 .next()
632 .is_none());
633 assert_eq!(
634 [LABEL_1_1_ID, PARAGRAPH_2_ID, LABEL_3_1_0_ID, BUTTON_3_2_ID],
635 tree.state()
636 .node_by_id(PARAGRAPH_0_ID)
637 .unwrap()
638 .following_filtered_siblings(test_tree_filter)
639 .map(|node| node.id())
640 .collect::<Vec<NodeId>>()[..]
641 );
642 assert_eq!(
643 [BUTTON_3_2_ID],
644 tree.state()
645 .node_by_id(LABEL_3_1_0_ID)
646 .unwrap()
647 .following_filtered_siblings(test_tree_filter)
648 .map(|node| node.id())
649 .collect::<Vec<NodeId>>()[..]
650 );
651 assert!(tree
652 .state()
653 .node_by_id(PARAGRAPH_3_IGNORED_ID)
654 .unwrap()
655 .following_filtered_siblings(test_tree_filter)
656 .next()
657 .is_none());
658 }
659
660 #[test]
661 fn following_filtered_siblings_reversed() {
662 let tree = test_tree();
663 assert!(tree
664 .state()
665 .root()
666 .following_filtered_siblings(test_tree_filter)
667 .next_back()
668 .is_none());
669 assert_eq!(
670 [BUTTON_3_2_ID, LABEL_3_1_0_ID, PARAGRAPH_2_ID, LABEL_1_1_ID],
671 tree.state()
672 .node_by_id(PARAGRAPH_0_ID)
673 .unwrap()
674 .following_filtered_siblings(test_tree_filter)
675 .rev()
676 .map(|node| node.id())
677 .collect::<Vec<NodeId>>()[..]
678 );
679 assert_eq!(
680 [BUTTON_3_2_ID,],
681 tree.state()
682 .node_by_id(LABEL_3_1_0_ID)
683 .unwrap()
684 .following_filtered_siblings(test_tree_filter)
685 .rev()
686 .map(|node| node.id())
687 .collect::<Vec<NodeId>>()[..]
688 );
689 assert!(tree
690 .state()
691 .node_by_id(PARAGRAPH_3_IGNORED_ID)
692 .unwrap()
693 .following_filtered_siblings(test_tree_filter)
694 .next_back()
695 .is_none());
696 }
697
698 #[test]
699 fn preceding_filtered_siblings() {
700 let tree = test_tree();
701 assert!(tree
702 .state()
703 .root()
704 .preceding_filtered_siblings(test_tree_filter)
705 .next()
706 .is_none());
707 assert_eq!(
708 [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
709 tree.state()
710 .node_by_id(PARAGRAPH_3_IGNORED_ID)
711 .unwrap()
712 .preceding_filtered_siblings(test_tree_filter)
713 .map(|node| node.id())
714 .collect::<Vec<NodeId>>()[..]
715 );
716 assert_eq!(
717 [PARAGRAPH_2_ID, LABEL_1_1_ID, PARAGRAPH_0_ID],
718 tree.state()
719 .node_by_id(LABEL_3_1_0_ID)
720 .unwrap()
721 .preceding_filtered_siblings(test_tree_filter)
722 .map(|node| node.id())
723 .collect::<Vec<NodeId>>()[..]
724 );
725 assert!(tree
726 .state()
727 .node_by_id(PARAGRAPH_0_ID)
728 .unwrap()
729 .preceding_filtered_siblings(test_tree_filter)
730 .next()
731 .is_none());
732 }
733
734 #[test]
735 fn preceding_filtered_siblings_reversed() {
736 let tree = test_tree();
737 assert!(tree
738 .state()
739 .root()
740 .preceding_filtered_siblings(test_tree_filter)
741 .next_back()
742 .is_none());
743 assert_eq!(
744 [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
745 tree.state()
746 .node_by_id(PARAGRAPH_3_IGNORED_ID)
747 .unwrap()
748 .preceding_filtered_siblings(test_tree_filter)
749 .rev()
750 .map(|node| node.id())
751 .collect::<Vec<NodeId>>()[..]
752 );
753 assert_eq!(
754 [PARAGRAPH_0_ID, LABEL_1_1_ID, PARAGRAPH_2_ID],
755 tree.state()
756 .node_by_id(LABEL_3_1_0_ID)
757 .unwrap()
758 .preceding_filtered_siblings(test_tree_filter)
759 .rev()
760 .map(|node| node.id())
761 .collect::<Vec<NodeId>>()[..]
762 );
763 assert!(tree
764 .state()
765 .node_by_id(PARAGRAPH_0_ID)
766 .unwrap()
767 .preceding_filtered_siblings(test_tree_filter)
768 .next_back()
769 .is_none());
770 }
771
772 #[test]
773 fn filtered_children() {
774 let tree = test_tree();
775 assert_eq!(
776 [
777 PARAGRAPH_0_ID,
778 LABEL_1_1_ID,
779 PARAGRAPH_2_ID,
780 LABEL_3_1_0_ID,
781 BUTTON_3_2_ID
782 ],
783 tree.state()
784 .root()
785 .filtered_children(test_tree_filter)
786 .map(|node| node.id())
787 .collect::<Vec<NodeId>>()[..]
788 );
789 assert!(tree
790 .state()
791 .node_by_id(PARAGRAPH_0_ID)
792 .unwrap()
793 .filtered_children(test_tree_filter)
794 .next()
795 .is_none());
796 assert!(tree
797 .state()
798 .node_by_id(LABEL_0_0_IGNORED_ID)
799 .unwrap()
800 .filtered_children(test_tree_filter)
801 .next()
802 .is_none());
803 }
804
805 #[test]
806 fn filtered_children_reversed() {
807 let tree = test_tree();
808 assert_eq!(
809 [
810 BUTTON_3_2_ID,
811 LABEL_3_1_0_ID,
812 PARAGRAPH_2_ID,
813 LABEL_1_1_ID,
814 PARAGRAPH_0_ID
815 ],
816 tree.state()
817 .root()
818 .filtered_children(test_tree_filter)
819 .rev()
820 .map(|node| node.id())
821 .collect::<Vec<NodeId>>()[..]
822 );
823 assert!(tree
824 .state()
825 .node_by_id(PARAGRAPH_0_ID)
826 .unwrap()
827 .filtered_children(test_tree_filter)
828 .next_back()
829 .is_none());
830 assert!(tree
831 .state()
832 .node_by_id(LABEL_0_0_IGNORED_ID)
833 .unwrap()
834 .filtered_children(test_tree_filter)
835 .next_back()
836 .is_none());
837 }
838}