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