diff --git a/consumer/src/iterators.rs b/consumer/src/iterators.rs index 6f01203c7..3213c6f08 100644 --- a/consumer/src/iterators.rs +++ b/consumer/src/iterators.rs @@ -13,7 +13,6 @@ use std::iter::FusedIterator; use accesskit_schema::NodeId; use crate::node::Node; -use crate::tree::Reader as TreeReader; /// An iterator that yields following siblings of a node. /// @@ -26,7 +25,7 @@ pub struct FollowingSiblings<'a> { } impl<'a> FollowingSiblings<'a> { - pub(crate) fn new(node: &'a Node<'a>) -> Self { + pub(crate) fn new(node: Node<'a>) -> Self { let parent_and_index = node.parent_and_index(); let (back_position, front_position, done) = if let Some((ref parent, index)) = parent_and_index { @@ -110,7 +109,7 @@ pub struct PrecedingSiblings<'a> { } impl<'a> PrecedingSiblings<'a> { - pub(crate) fn new(node: &'a Node<'a>) -> Self { + pub(crate) fn new(node: Node<'a>) -> Self { let parent_and_index = node.parent_and_index(); let (back_position, front_position, done) = if let Some((_, index)) = parent_and_index { let front_position = index.saturating_sub(1); @@ -179,7 +178,7 @@ impl<'a> ExactSizeIterator for PrecedingSiblings<'a> {} impl<'a> FusedIterator for PrecedingSiblings<'a> {} -fn next_unignored_sibling(node_id: Option, reader: &TreeReader) -> Option { +fn next_unignored_sibling(node: Option) -> Option { // Search for the next sibling of this node, skipping over any ignored nodes // encountered. // @@ -190,23 +189,23 @@ fn next_unignored_sibling(node_id: Option, reader: &TreeReader) -> Optio // // Note: this behaviour of 'skipping over' an ignored node makes this subtly // different to finding the next (direct) sibling which is unignored. - let mut next_id = node_id; + let mut next = node; let mut consider_children = false; - while let Some(current_node) = next_id.and_then(|id| reader.node_by_id(id)) { - if let Some(Some(child)) = consider_children.then(|| current_node.children().next()) { - next_id = Some(child.id()); + while let Some(current) = next { + if let Some(Some(child)) = consider_children.then(|| current.children().next()) { + next = Some(child); if !child.is_ignored() { - return next_id; + return next; } - } else if let Some(sibling) = current_node.following_siblings().next() { - next_id = Some(sibling.id()); + } else if let Some(sibling) = current.following_siblings().next() { + next = Some(sibling); if !sibling.is_ignored() { - return next_id; + return next; } consider_children = true; } else { - let parent = current_node.parent(); - next_id = parent.as_ref().map(|parent| parent.id()); + let parent = current.parent(); + next = parent; if let Some(parent) = parent { if !parent.is_ignored() { return None; @@ -219,7 +218,7 @@ fn next_unignored_sibling(node_id: Option, reader: &TreeReader) -> Optio None } -fn previous_unignored_sibling(node_id: Option, reader: &TreeReader) -> Option { +fn previous_unignored_sibling(node: Option) -> Option { // Search for the previous sibling of this node, skipping over any ignored nodes // encountered. // @@ -227,23 +226,23 @@ fn previous_unignored_sibling(node_id: Option, reader: &TreeReader) -> O // If we find an ignored sibling, we may consider its children as siblings. // If we run out of siblings, we may consider an ignored parent's siblings as // our own. - let mut previous_id = node_id; + let mut previous = node; let mut consider_children = false; - while let Some(current_node) = previous_id.and_then(|id| reader.node_by_id(id)) { - if let Some(Some(child)) = consider_children.then(|| current_node.children().next_back()) { - previous_id = Some(child.id()); + while let Some(current) = previous { + if let Some(Some(child)) = consider_children.then(|| current.children().next_back()) { + previous = Some(child); if !child.is_ignored() { - return previous_id; + return previous; } - } else if let Some(sibling) = current_node.preceding_siblings().next() { - previous_id = Some(sibling.id()); + } else if let Some(sibling) = current.preceding_siblings().next() { + previous = Some(sibling); if !sibling.is_ignored() { - return previous_id; + return previous; } consider_children = true; } else { - let parent = current_node.parent(); - previous_id = parent.as_ref().map(|parent| parent.id()); + let parent = current.parent(); + previous = parent; if let Some(parent) = parent { if !parent.is_ignored() { return None; @@ -260,36 +259,34 @@ fn previous_unignored_sibling(node_id: Option, reader: &TreeReader) -> O /// /// This struct is created by the [following_unignored_siblings](Node::following_unignored_siblings) method on [Node]. pub struct FollowingUnignoredSiblings<'a> { - back_id: Option, + back: Option>, done: bool, - front_id: Option, - reader: &'a TreeReader<'a>, + front: Option>, } impl<'a> FollowingUnignoredSiblings<'a> { - pub(crate) fn new(node: &'a Node<'a>) -> Self { - let front_id = next_unignored_sibling(Some(node.id()), node.tree_reader); - let back_id = node.parent().as_ref().and_then(Node::last_unignored_child); + pub(crate) fn new(node: Node<'a>) -> Self { + let front = next_unignored_sibling(Some(node)); + let back = node.parent().and_then(Node::last_unignored_child); Self { - back_id, - done: back_id.is_none() || front_id.is_none(), - front_id, - reader: node.tree_reader, + back, + done: back.is_none() || front.is_none(), + front, } } } impl<'a> Iterator for FollowingUnignoredSiblings<'a> { - type Item = NodeId; + type Item = Node<'a>; fn next(&mut self) -> Option { if self.done { None } else { - self.done = self.front_id == self.back_id; - let current_id = self.front_id; - self.front_id = next_unignored_sibling(self.front_id, self.reader); - current_id + self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id(); + let current = self.front; + self.front = next_unignored_sibling(self.front); + current } } } @@ -299,10 +296,10 @@ impl<'a> DoubleEndedIterator for FollowingUnignoredSiblings<'a> { if self.done { None } else { - self.done = self.back_id == self.front_id; - let current_id = self.back_id; - self.back_id = previous_unignored_sibling(self.back_id, self.reader); - current_id + self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id(); + let current = self.back; + self.back = previous_unignored_sibling(self.back); + current } } } @@ -313,36 +310,34 @@ impl<'a> FusedIterator for FollowingUnignoredSiblings<'a> {} /// /// This struct is created by the [preceding_unignored_siblings](Node::preceding_unignored_siblings) method on [Node]. pub struct PrecedingUnignoredSiblings<'a> { - back_id: Option, + back: Option>, done: bool, - front_id: Option, - reader: &'a TreeReader<'a>, + front: Option>, } impl<'a> PrecedingUnignoredSiblings<'a> { - pub(crate) fn new(node: &'a Node<'a>) -> Self { - let front_id = previous_unignored_sibling(Some(node.id()), node.tree_reader); - let back_id = node.parent().as_ref().and_then(Node::first_unignored_child); + pub(crate) fn new(node: Node<'a>) -> Self { + let front = previous_unignored_sibling(Some(node)); + let back = node.parent().and_then(Node::first_unignored_child); Self { - back_id, - done: back_id.is_none() || front_id.is_none(), - front_id, - reader: node.tree_reader, + back, + done: back.is_none() || front.is_none(), + front, } } } impl<'a> Iterator for PrecedingUnignoredSiblings<'a> { - type Item = NodeId; + type Item = Node<'a>; fn next(&mut self) -> Option { if self.done { None } else { - self.done = self.front_id == self.back_id; - let current_id = self.front_id; - self.front_id = previous_unignored_sibling(self.front_id, self.reader); - current_id + self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id(); + let current = self.front; + self.front = previous_unignored_sibling(self.front); + current } } } @@ -352,10 +347,10 @@ impl<'a> DoubleEndedIterator for PrecedingUnignoredSiblings<'a> { if self.done { None } else { - self.done = self.back_id == self.front_id; - let current_id = self.back_id; - self.back_id = next_unignored_sibling(self.back_id, self.reader); - current_id + self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id(); + let current = self.back; + self.back = next_unignored_sibling(self.back); + current } } } @@ -366,36 +361,34 @@ impl<'a> FusedIterator for PrecedingUnignoredSiblings<'a> {} /// /// This struct is created by the [unignored_children](Node::unignored_children) method on [Node]. pub struct UnignoredChildren<'a> { - back_id: Option, + back: Option>, done: bool, - front_id: Option, - reader: &'a TreeReader<'a>, + front: Option>, } impl<'a> UnignoredChildren<'a> { - pub(crate) fn new(node: &'a Node<'a>) -> Self { - let front_id = node.first_unignored_child(); - let back_id = node.last_unignored_child(); + pub(crate) fn new(node: Node<'a>) -> Self { + let front = node.first_unignored_child(); + let back = node.last_unignored_child(); Self { - back_id, - done: back_id.is_none() || front_id.is_none(), - front_id, - reader: node.tree_reader, + back, + done: back.is_none() || front.is_none(), + front, } } } impl<'a> Iterator for UnignoredChildren<'a> { - type Item = NodeId; + type Item = Node<'a>; fn next(&mut self) -> Option { if self.done { None } else { - self.done = self.front_id == self.back_id; - let current_id = self.front_id; - self.front_id = next_unignored_sibling(self.front_id, self.reader); - current_id + self.done = self.front.as_ref().unwrap().id() == self.back.as_ref().unwrap().id(); + let current = self.front; + self.front = next_unignored_sibling(self.front); + current } } } @@ -405,10 +398,10 @@ impl<'a> DoubleEndedIterator for UnignoredChildren<'a> { if self.done { None } else { - self.done = self.back_id == self.front_id; - let current_id = self.back_id; - self.back_id = previous_unignored_sibling(self.back_id, self.reader); - current_id + self.done = self.back.as_ref().unwrap().id() == self.front.as_ref().unwrap().id(); + let current = self.back; + self.back = previous_unignored_sibling(self.back); + current } } } diff --git a/consumer/src/node.rs b/consumer/src/node.rs index db57acd5c..893a1452e 100644 --- a/consumer/src/node.rs +++ b/consumer/src/node.rs @@ -15,12 +15,13 @@ use crate::iterators::{ use crate::tree::{NodeState, ParentAndIndex, Reader as TreeReader, Tree}; use crate::NodeData; +#[derive(Copy, Clone)] pub struct Node<'a> { pub tree_reader: &'a TreeReader<'a>, pub(crate) state: &'a NodeState, } -impl Node<'_> { +impl<'a> Node<'a> { pub fn data(&self) -> &NodeData { &self.state.data } @@ -37,7 +38,7 @@ impl Node<'_> { (self.is_invisible() || self.is_ignored()) && !self.is_focused() } - pub fn parent(&self) -> Option> { + pub fn parent(self) -> Option> { if let Some(ParentAndIndex(parent, _)) = &self.state.parent_and_index { Some(self.tree_reader.node_by_id(*parent).unwrap()) } else { @@ -45,13 +46,10 @@ impl Node<'_> { } } - pub fn unignored_parent(&self) -> Option> { + pub fn unignored_parent(self) -> Option> { if let Some(parent) = self.parent() { if parent.is_ignored() { - // Work around lifetime issues. - parent - .unignored_parent() - .map(|node| self.tree_reader.node_by_id(node.id()).unwrap()) + parent.unignored_parent() } else { Some(parent) } @@ -60,7 +58,7 @@ impl Node<'_> { } } - pub fn parent_and_index(&self) -> Option<(Node<'_>, usize)> { + pub fn parent_and_index(self) -> Option<(Node<'a>, usize)> { self.state .parent_and_index .as_ref() @@ -70,107 +68,86 @@ impl Node<'_> { } pub fn children( - &self, - ) -> impl DoubleEndedIterator> - + ExactSizeIterator> - + FusedIterator> { - self.data() - .children + self, + ) -> impl DoubleEndedIterator> + + ExactSizeIterator> + + FusedIterator> + + 'a { + let data = &self.state.data; + let reader = self.tree_reader; + data.children .iter() - .map(move |id| self.tree_reader.node_by_id(*id).unwrap()) + .map(move |id| reader.node_by_id(*id).unwrap()) } pub fn unignored_children( - &self, - ) -> impl DoubleEndedIterator> + FusedIterator> { - UnignoredChildren::new(self).map(move |id| self.tree_reader.node_by_id(id).unwrap()) + self, + ) -> impl DoubleEndedIterator> + FusedIterator> + 'a { + UnignoredChildren::new(self) } pub fn following_siblings( - &self, - ) -> impl DoubleEndedIterator> - + ExactSizeIterator> - + FusedIterator> { - FollowingSiblings::new(self).map(move |id| self.tree_reader.node_by_id(id).unwrap()) + self, + ) -> impl DoubleEndedIterator> + + ExactSizeIterator> + + FusedIterator> + + 'a { + let reader = self.tree_reader; + FollowingSiblings::new(self).map(move |id| reader.node_by_id(id).unwrap()) } pub fn following_unignored_siblings( - &self, - ) -> impl DoubleEndedIterator> + FusedIterator> { + self, + ) -> impl DoubleEndedIterator> + FusedIterator> + 'a { FollowingUnignoredSiblings::new(self) - .map(move |id| self.tree_reader.node_by_id(id).unwrap()) } pub fn preceding_siblings( - &self, - ) -> impl DoubleEndedIterator> - + ExactSizeIterator> - + FusedIterator> { - PrecedingSiblings::new(self).map(move |id| self.tree_reader.node_by_id(id).unwrap()) + self, + ) -> impl DoubleEndedIterator> + + ExactSizeIterator> + + FusedIterator> + + 'a { + let reader = self.tree_reader; + PrecedingSiblings::new(self).map(move |id| reader.node_by_id(id).unwrap()) } pub fn preceding_unignored_siblings( - &self, - ) -> impl DoubleEndedIterator> + FusedIterator> { + self, + ) -> impl DoubleEndedIterator> + FusedIterator> + 'a { PrecedingUnignoredSiblings::new(self) - .map(move |id| self.tree_reader.node_by_id(id).unwrap()) } - pub fn deepest_first_child(&self) -> Option> { - let mut deepest_child = *self.data().children.get(0)?; - while let Some(first_child) = self - .tree_reader - .node_by_id(deepest_child) - .unwrap() - .data() - .children - .get(0) - { - deepest_child = *first_child; + pub fn deepest_first_child(self) -> Option> { + let mut deepest_child = self.children().next()?; + while let Some(first_child) = deepest_child.children().next() { + deepest_child = first_child; } - self.tree_reader.node_by_id(deepest_child) + Some(deepest_child) } - pub fn deepest_first_unignored_child(&self) -> Option> { + pub fn deepest_first_unignored_child(self) -> Option> { let mut deepest_child = self.first_unignored_child()?; - while let Some(first_child) = self - .tree_reader - .node_by_id(deepest_child) - .unwrap() - .first_unignored_child() - { + while let Some(first_child) = deepest_child.first_unignored_child() { deepest_child = first_child; } - self.tree_reader.node_by_id(deepest_child) + Some(deepest_child) } - pub fn deepest_last_child(&self) -> Option> { - let mut deepest_child = *self.data().children.iter().next_back()?; - while let Some(last_child) = self - .tree_reader - .node_by_id(deepest_child) - .unwrap() - .data() - .children - .iter() - .next_back() - { - deepest_child = *last_child; + pub fn deepest_last_child(self) -> Option> { + let mut deepest_child = self.children().next_back()?; + while let Some(last_child) = deepest_child.children().next_back() { + deepest_child = last_child; } - self.tree_reader.node_by_id(deepest_child) + Some(deepest_child) } - pub fn deepest_last_unignored_child(&self) -> Option> { + pub fn deepest_last_unignored_child(self) -> Option> { let mut deepest_child = self.last_unignored_child()?; - while let Some(last_child) = self - .tree_reader - .node_by_id(deepest_child) - .unwrap() - .last_unignored_child() - { + while let Some(last_child) = deepest_child.last_unignored_child() { deepest_child = last_child; } - self.tree_reader.node_by_id(deepest_child) + Some(deepest_child) } pub fn is_descendant_of(&self, ancestor: &Node) -> bool { @@ -222,10 +199,10 @@ impl Node<'_> { } } - pub(crate) fn first_unignored_child(&self) -> Option { + pub(crate) fn first_unignored_child(self) -> Option> { for child in self.children() { if !child.is_ignored() { - return Some(child.id()); + return Some(child); } if let Some(descendant) = child.first_unignored_child() { return Some(descendant); @@ -234,10 +211,10 @@ impl Node<'_> { None } - pub(crate) fn last_unignored_child(&self) -> Option { + pub(crate) fn last_unignored_child(self) -> Option> { for child in self.children().rev() { if !child.is_ignored() { - return Some(child.id()); + return Some(child); } if let Some(descendant) = child.last_unignored_child() { return Some(descendant);