Refactored `tree_rev` to not be a DoubledEndedIterator, this allows splitting the implementation in two and changing the API expectations of where the iterators start and stop.

This commit is contained in:
Samuel Guerra 2022-07-13 01:23:09 -03:00
parent b6370c8216
commit a97bb6c2ae
7 changed files with 203 additions and 330 deletions

View File

@ -1218,7 +1218,6 @@ pub fn focus_goes_to_parent_after_remove() {
assert_eq!(Some(child_id), app.focused());
app.take_focus_changed();
println!("!!: JUST BEFORE INTERACTIVE BLOCKED");
app.set_vars(|vars| {
interactive.set(vars, false);
});

View File

@ -1443,7 +1443,6 @@ trait EnabledNavWithFrameExt {
impl<'a> EnabledNavWithFrameExt for WidgetFocusInfo<'a> {
fn enabled_nav_with_frame(self) -> EnabledNavWithFrame {
let stats = self.info.tree().stats();
println!("!!: ENABLED_NAV, {:?}", stats.last_frame);
EnabledNavWithFrame {
nav: self.enabled_nav(),
spatial_frame_id: stats.bounds_updated_frame,

View File

@ -651,13 +651,13 @@ impl<'a> WidgetFocusInfo<'a> {
}
/// Iterator over the focusable widgets contained by this widget.
pub fn descendants(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> {
super::iter::FocusableDescendants::new(self.info.descendants(), self.focus_disabled_widgets())
pub fn descendants(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> {
super::iter::FocusTreeIter::new(self.info.descendants(), self.focus_disabled_widgets())
}
/// Iterator over self and the focusable widgets contained by it.
pub fn self_and_descendants(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> {
super::iter::FocusableDescendants::new(self.info.self_and_descendants(), self.focus_disabled_widgets())
pub fn self_and_descendants(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> {
super::iter::FocusTreeIter::new(self.info.self_and_descendants(), self.focus_disabled_widgets())
}
/// If the focusable has any focusable descendant that is not [`TabIndex::SKIP`]
@ -688,7 +688,7 @@ impl<'a> WidgetFocusInfo<'a> {
pub fn last_tab_descendant(self) -> Option<WidgetFocusInfo<'a>> {
let mut best = (-1i64, self);
for d in self.descendants().tree_filter(Self::filter_tab_skip).rev() {
for d in self.descendants().tree_rev().tree_filter(Self::filter_tab_skip) {
let idx = d.focus_info().tab_index().0 as i64;
if idx > best.0 {
@ -704,12 +704,12 @@ impl<'a> WidgetFocusInfo<'a> {
}
/// Iterator over all focusable widgets in the same scope after this widget.
pub fn next_focusables(self) -> super::iter::FocusableDescendants<'a, iter::TreeIter<'a>> {
pub fn next_focusables(self) -> super::iter::FocusTreeIter<'a, iter::TreeIter<'a>> {
if let Some(scope) = self.scope() {
super::iter::FocusableDescendants::new(self.info.next_siblings_in(scope.info), self.focus_disabled_widgets())
super::iter::FocusTreeIter::new(self.info.next_siblings_in(scope.info), self.focus_disabled_widgets())
} else {
// empty
super::iter::FocusableDescendants::new(self.info.next_siblings_in(self.info), self.focus_disabled_widgets())
super::iter::FocusTreeIter::new(self.info.next_siblings_in(self.info), self.focus_disabled_widgets())
}
}
@ -791,12 +791,12 @@ impl<'a> WidgetFocusInfo<'a> {
}
/// Iterator over all focusable widgets in the same scope before this widget in reverse.
pub fn prev_focusables(self) -> super::iter::FocusableDescendants<'a, iter::RevTreeIter<'a, iter::TreeIter<'a>>> {
pub fn prev_focusables(self) -> super::iter::FocusTreeIter<'a, iter::RevTreeIter<'a>> {
if let Some(scope) = self.scope() {
super::iter::FocusableDescendants::new(self.info.prev_siblings_in(scope.info), self.focus_disabled_widgets())
super::iter::FocusTreeIter::new(self.info.prev_siblings_in(scope.info), self.focus_disabled_widgets())
} else {
// empty
super::iter::FocusableDescendants::new(self.info.prev_siblings_in(self.info), self.focus_disabled_widgets())
super::iter::FocusTreeIter::new(self.info.prev_siblings_in(self.info), self.focus_disabled_widgets())
}
}
@ -825,7 +825,7 @@ impl<'a> WidgetFocusInfo<'a> {
let mut best = (-1i64, self);
if !skip_self {
for d in self.descendants().tree_filter(Self::filter_tab_skip).rev() {
for d in self.descendants().tree_rev().tree_filter(Self::filter_tab_skip) {
let idx = d.focus_info().tab_index().0 as i64;
if idx == self_index {

View File

@ -74,7 +74,7 @@ where
///
/// [`descendants`]: WidgetFocusInfo::descendants
/// [`self_and_descendants`]: WidgetFocusInfo::self_and_descendants
pub struct FocusableDescendants<'a, I>
pub struct FocusTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
@ -82,7 +82,7 @@ where
iter: I,
focus_disabled_widgets: bool,
}
impl<'a, I> FocusableDescendants<'a, I>
impl<'a, I> FocusTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
@ -99,11 +99,11 @@ where
/// Note that you can convert `bool` into [`TreeFilter`] to use this method just like the iterator default.
///
/// [`TreeFilter`]: w_iter::TreeFilter
pub fn tree_filter<F>(self, mut filter: F) -> FocusableFilterDescendants<'a, I, impl FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter>
pub fn tree_filter<F>(self, mut filter: F) -> FocusTreeFilterIter<'a, I, impl FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter>
where
F: FnMut(WidgetFocusInfo<'a>) -> w_iter::TreeFilter,
{
FocusableFilterDescendants {
FocusTreeFilterIter {
iter: self.iter.tree_filter(move |w| {
if let Some(f) = w.as_focusable(self.focus_disabled_widgets) {
filter(f)
@ -140,7 +140,14 @@ where
self.tree_find(filter).is_some()
}
}
impl<'a, I> Iterator for FocusableDescendants<'a, I>
impl<'a> FocusTreeIter<'a, w_iter::TreeIter<'a>> {
/// Creates a reverse tree iterator.
pub fn tree_rev(self) -> FocusTreeIter<'a, w_iter::RevTreeIter<'a>> {
FocusTreeIter::new(self.iter.tree_rev(), self.focus_disabled_widgets)
}
}
impl<'a, I> Iterator for FocusTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
@ -155,24 +162,11 @@ where
None
}
}
impl<'a, I> DoubleEndedIterator for FocusableDescendants<'a, I>
where
I: TreeIterator<'a>,
{
fn next_back(&mut self) -> Option<Self::Item> {
while let Some(next) = self.iter.next_back() {
if let Some(next) = next.as_focusable(self.focus_disabled_widgets) {
return Some(next);
}
}
None
}
}
/// An iterator that filters a focusable widget tree.
///
/// This `struct` is created by the [`FocusableDescendants::tree_filter`] method. See its documentation for more.
pub struct FocusableFilterDescendants<'a, I, F>
/// This `struct` is created by the [`FocusTreeIter::tree_filter`] method. See its documentation for more.
pub struct FocusTreeFilterIter<'a, I, F>
where
I: TreeIterator<'a>,
F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter,
@ -180,7 +174,7 @@ where
iter: w_iter::TreeFilterIter<'a, I, F>,
focus_disabled_widgets: bool,
}
impl<'a, I, F> Iterator for FocusableFilterDescendants<'a, I, F>
impl<'a, I, F> Iterator for FocusTreeFilterIter<'a, I, F>
where
F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter,
I: TreeIterator<'a>,
@ -191,12 +185,3 @@ where
self.iter.next().map(|w| w.as_focus_info(self.focus_disabled_widgets))
}
}
impl<'a, I, F> DoubleEndedIterator for FocusableFilterDescendants<'a, I, F>
where
F: FnMut(WidgetInfo<'a>) -> w_iter::TreeFilter,
I: TreeIterator<'a>,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|w| w.as_focus_info(self.focus_disabled_widgets))
}
}

View File

@ -1400,7 +1400,6 @@ impl<'a> WidgetInfo<'a> {
pub fn descendants(self) -> iter::TreeIter<'a> {
let mut d = self.self_and_descendants();
d.next();
d.next_back();
d
}
@ -1473,7 +1472,7 @@ impl<'a> WidgetInfo<'a> {
/// Iterator over all previous widgets within the same `ancestor`, including descendants of siblings.
///
/// If `ancestor` is not actually an ancestor iterates to the root.
pub fn prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a, iter::TreeIter<'a>> {
pub fn prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a> {
let mut r = self.self_and_prev_siblings_in(ancestor);
r.next();
r
@ -1482,7 +1481,7 @@ impl<'a> WidgetInfo<'a> {
/// Iterator over self, descendants and all previous widgets within the same `ancestor`.
///
/// If `ancestor` is not actually an ancestor iterates to the root.
pub fn self_and_prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a, iter::TreeIter<'a>> {
pub fn self_and_prev_siblings_in(self, ancestor: WidgetInfo<'a>) -> iter::RevTreeIter<'a> {
iter::TreeIter::self_and_prev_siblings_in(self, ancestor)
}

View File

@ -179,25 +179,12 @@ impl<'a> Iterator for Ancestors<'a> {
mod internal {
pub trait InternalTreeIterator {
fn skip_all(&mut self, widget: super::WidgetInfo, rev: bool);
fn skip_all(&mut self, widget: super::WidgetInfo);
}
}
/// Iterator that traverses the branches of a widget tree.
pub trait TreeIterator<'a>: internal::InternalTreeIterator + Iterator<Item = WidgetInfo<'a>> + DoubleEndedIterator + FusedIterator {
/// Reverse tree iterator direction.
///
/// Yields the same widgets as [`Iterator::rev`], but is also a [`TreeIterator`] so can be filtered.
fn tree_rev(self) -> RevTreeIter<'a, Self>
where
Self: Sized,
{
RevTreeIter {
_lt: PhantomData,
iter: self,
}
}
pub trait TreeIterator<'a>: internal::InternalTreeIterator + Iterator<Item = WidgetInfo<'a>> + FusedIterator {
/// Creates an iterator which uses a closure to filter items or branches at a time.
///
/// See [`TreeFilter`] for details.
@ -242,10 +229,12 @@ impl<'a> TreeIter<'a> {
}
}
pub(super) fn self_and_prev_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> RevTreeIter<'a, Self> {
let mut iter = ancestor.node().self_and_descendants();
iter.skip_back_to(wgt.node_id, &wgt.tree.0.tree);
Self { tree: wgt.tree(), iter }.tree_rev()
pub(super) fn self_and_prev_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> RevTreeIter<'a> {
let tree = &wgt.tree.0.tree;
let mut iter = ancestor.node().self_and_descendants().rev(tree);
iter.skip_to(tree, wgt.node_id);
RevTreeIter { tree: wgt.tree, iter }
}
pub(super) fn self_and_next_siblings_in(wgt: WidgetInfo<'a>, ancestor: WidgetInfo<'a>) -> Self {
@ -253,14 +242,28 @@ impl<'a> TreeIter<'a> {
iter.skip_to(wgt.node_id);
Self { tree: wgt.tree(), iter }
}
/// Creates a reverse tree iterator.
///
/// Yields widgets in the `parent -> last_child -> prev_sibling` order. The reverse iterator is pre-advanced by the same count
/// of widgets already yielded by this iterator. In practice this is best used immediatly after getting the iterator from
/// [`self_descendants`] or [`descendants`], with the intention of skipping to the last child from the starting widget.
///
/// [`self_descendants`]: WidgetInfo::self_descendants
/// [`descendants`]: WidgetInfo::descendants
pub fn tree_rev(self) -> RevTreeIter<'a>
where
Self: Sized,
{
RevTreeIter {
tree: self.tree,
iter: self.iter.rev(&self.tree.0.tree),
}
}
}
impl<'a> internal::InternalTreeIterator for TreeIter<'a> {
fn skip_all(&mut self, widget: WidgetInfo, rev: bool) {
if rev {
self.iter.close_back(&self.tree.0.tree, widget.node_id)
} else {
self.iter.close(&self.tree.0.tree, widget.node_id)
}
fn skip_all(&mut self, widget: WidgetInfo) {
self.iter.close(&self.tree.0.tree, widget.node_id)
}
}
impl<'a> Iterator for TreeIter<'a> {
@ -275,11 +278,6 @@ impl<'a> Iterator for TreeIter<'a> {
(len, Some(len))
}
}
impl<'a> DoubleEndedIterator for TreeIter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back(&self.tree.0.tree).map(|id| WidgetInfo::new(self.tree, id))
}
}
impl<'a> ExactSizeIterator for TreeIter<'a> {
fn len(&self) -> usize {
self.iter.len()
@ -291,50 +289,24 @@ impl<'a> TreeIterator<'a> for TreeIter<'a> {}
/// Reversing tree iterator.
///
/// This struct is created by the [`TreeIterator::tree_rev`] method.
pub struct RevTreeIter<'a, I: TreeIterator<'a>> {
_lt: PhantomData<&'a WidgetInfoTree>,
iter: I,
pub struct RevTreeIter<'a> {
tree: &'a WidgetInfoTree,
iter: tree::RevTreeIter,
}
impl<'a, I> internal::InternalTreeIterator for RevTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
fn skip_all(&mut self, widget: WidgetInfo, rev: bool) {
self.iter.skip_all(widget, !rev)
impl<'a> internal::InternalTreeIterator for RevTreeIter<'a> {
fn skip_all(&mut self, widget: WidgetInfo) {
self.iter.close(&self.tree.0.tree, widget.node_id);
}
}
impl<'a, I> Iterator for RevTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
impl<'a> Iterator for RevTreeIter<'a> {
type Item = WidgetInfo<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next_back()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
self.iter.next(&self.tree.0.tree).map(|id| WidgetInfo::new(self.tree, id))
}
}
impl<'a, I> DoubleEndedIterator for RevTreeIter<'a, I>
where
I: TreeIterator<'a>,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next()
}
}
impl<'a, I> ExactSizeIterator for RevTreeIter<'a, I>
where
I: TreeIterator<'a> + ExactSizeIterator,
{
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, I> FusedIterator for RevTreeIter<'a, I> where I: TreeIterator<'a> {}
impl<'a, I> TreeIterator<'a> for RevTreeIter<'a, I> where I: TreeIterator<'a> {}
impl<'a> FusedIterator for RevTreeIter<'a> {}
impl<'a> TreeIterator<'a> for RevTreeIter<'a> {}
/// Filtering tree iterator.
///
@ -345,8 +317,8 @@ pub struct TreeFilterIter<'a, I: TreeIterator<'a>, F: FnMut(WidgetInfo<'a>) -> T
filter: F,
}
impl<'a, I: TreeIterator<'a>, F: FnMut(WidgetInfo<'a>) -> TreeFilter> internal::InternalTreeIterator for TreeFilterIter<'a, I, F> {
fn skip_all(&mut self, widget: WidgetInfo, rev: bool) {
self.iter.skip_all(widget, rev)
fn skip_all(&mut self, widget: WidgetInfo) {
self.iter.skip_all(widget)
}
}
impl<'a, I, F> Iterator for TreeFilterIter<'a, I, F>
@ -363,36 +335,11 @@ where
TreeFilter::Include => return Some(wgt),
TreeFilter::Skip => continue,
TreeFilter::SkipAll => {
self.iter.skip_all(wgt, false);
self.iter.skip_all(wgt);
continue;
}
TreeFilter::SkipDescendants => {
self.iter.skip_all(wgt, false);
return Some(wgt);
}
},
None => return None,
}
}
}
}
impl<'a, I, F> DoubleEndedIterator for TreeFilterIter<'a, I, F>
where
I: TreeIterator<'a>,
F: FnMut(WidgetInfo<'a>) -> TreeFilter,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next_back() {
Some(wgt) => match (self.filter)(wgt) {
TreeFilter::Include => return Some(wgt),
TreeFilter::Skip => continue,
TreeFilter::SkipAll => {
self.iter.skip_all(wgt, true);
continue;
}
TreeFilter::SkipDescendants => {
self.iter.skip_all(wgt, true);
self.iter.skip_all(wgt);
return Some(wgt);
}
},
@ -500,8 +447,8 @@ mod tests {
let result: Vec<_> = tree
.root()
.descendants()
.tree_filter(|_| TreeFilter::Include)
.tree_rev()
.tree_filter(|_| TreeFilter::Include)
.map(|w| w.test_name())
.collect();
@ -547,8 +494,8 @@ mod tests {
let result: Vec<_> = tree
.root()
.self_and_descendants()
.tree_filter(|_| TreeFilter::Include)
.tree_rev()
.tree_filter(|_| TreeFilter::Include)
.map(|w| w.test_name())
.collect();
@ -564,19 +511,19 @@ mod tests {
let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect();
assert_eq!(result, vec!["c-2", "c-1"]);
assert_eq!(result, vec!["c-1", "c-0"]);
}
#[test]
fn descendants_double_filter_noop() {
let tree = data();
let mut iter = tree.root().descendants().tree_filter(|_| TreeFilter::Include);
let mut iter = tree.root().descendants().tree_rev().tree_filter(|_| TreeFilter::Include);
assert_eq!(iter.next().map(|w| w.test_name()), Some("c-0"));
assert_eq!(iter.next().map(|w| w.test_name()), Some("c-2"));
let result: Vec<_> = iter.tree_rev().map(|w| w.test_name()).collect();
let result: Vec<_> = iter.map(|w| w.test_name()).collect();
assert_eq!(result, vec!["c-2", "c-1"]);
assert_eq!(result, vec!["c-1", "c-0"]);
}
fn data_nested() -> WidgetInfoTree {
@ -680,7 +627,7 @@ mod tests {
assert_eq!(
result,
vec![
"c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1",
"c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1",
"c-0-0",
]
);
@ -698,7 +645,7 @@ mod tests {
assert_eq!(
result,
vec!["c-2", "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1"]
vec!["c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0"]
);
}
@ -805,6 +752,7 @@ mod tests {
let result: Vec<_> = tree
.root()
.descendants()
.tree_rev()
.tree_filter(|w| {
if w.widget_id() == WidgetId::named("c-1") {
TreeFilter::Skip
@ -812,7 +760,6 @@ mod tests {
TreeFilter::Include
}
})
.tree_rev()
.map(|w| w.test_name())
.collect();
@ -858,6 +805,7 @@ mod tests {
let result: Vec<_> = tree
.root()
.descendants()
.tree_rev()
.tree_filter(|w| {
if w.widget_id() == WidgetId::named("c-1") {
TreeFilter::SkipAll
@ -865,7 +813,6 @@ mod tests {
TreeFilter::Include
}
})
.tree_rev()
.map(|w| w.test_name())
.collect();
@ -911,6 +858,7 @@ mod tests {
let result: Vec<_> = tree
.root()
.descendants()
.tree_rev()
.tree_filter(|w| {
if w.widget_id() == WidgetId::named("c-1") {
TreeFilter::SkipDescendants
@ -918,7 +866,6 @@ mod tests {
TreeFilter::Include
}
})
.tree_rev()
.map(|w| w.test_name())
.collect();

View File

@ -184,10 +184,9 @@ impl<'a, T> NodeRef<'a, T> {
pub fn self_and_descendants(self) -> TreeIter {
let node = self.id.get();
TreeIter {
node,
next: node,
next_back: node,
end: self.tree.nodes[self.id.get()].descendants_end as usize,
back_advance: 0,
}
}
@ -271,11 +270,10 @@ impl<'a, T> NodeMut<'a, T> {
}
pub(super) struct TreeIter {
node: usize, // used for creating reverse iterator.
next: usize,
end: usize,
next_back: usize,
back_advance: usize, // number of nodes back entered
}
impl TreeIter {
/// for a tree (a(a.a, a.b, a.c), b)
@ -290,50 +288,6 @@ impl TreeIter {
}
}
/// for a tree (a(a.a, a.b, a.c), b)
/// yield [b, a, a.c, a.b, a.a]
pub fn next_back<T>(&mut self, tree: &Tree<T>) -> Option<NodeId> {
if self.next < self.end {
let next = NodeId::new(self.next_back);
let node = &tree.nodes[self.next_back];
if let Some(last_child) = node.last_child {
self.next_back = last_child.get();
self.back_advance += 1;
} else if let Some(prev_sibling) = node.prev_sibling {
self.next_back = prev_sibling.get();
self.end -= 1;
} else {
let mut node = node;
while self.next < self.end {
if let Some(parent) = node.parent {
self.end -= 1;
if self.end == self.next {
self.back_advance = 0;
break;
}
self.back_advance -= 1;
node = &tree.nodes[parent.get()];
if let Some(prev_sibling) = node.prev_sibling {
self.next_back = prev_sibling.get();
self.end -= 1;
break;
}
} else {
self.end = self.next;
self.back_advance = 0;
break;
}
}
}
Some(next)
} else {
None
}
}
/// Skip to the next sibling of the node last yielded by `next`.
pub fn close<T>(&mut self, tree: &Tree<T>, yielded: NodeId) {
let node = &tree.nodes[yielded.get()];
@ -347,30 +301,6 @@ impl TreeIter {
}
}
/// Skip to the prev sibling of the node last yielded by `next_back`.
pub fn close_back<T>(&mut self, tree: &Tree<T>, yielded: NodeId) {
let node = &tree.nodes[yielded.get()];
if let Some(prev_sibling) = node.prev_sibling {
self.next_back = prev_sibling.get();
self.end = tree.nodes[self.next_back].descendants_end as usize;
} else {
let mut node = node;
while let Some(parent) = node.parent {
node = &tree.nodes[parent.get()];
self.back_advance -= 1;
if let Some(prev_sibling) = node.prev_sibling {
self.next_back = self.next.max(prev_sibling.get() as usize);
self.end = tree.nodes[prev_sibling.get()].descendants_end as usize;
return;
}
}
// else
self.end = self.next;
self.next_back = self.next;
}
}
pub fn skip_to(&mut self, node: NodeId) {
let node = node.get() as usize;
if node > self.next {
@ -382,32 +312,107 @@ impl TreeIter {
}
}
pub fn skip_back_to<T>(&mut self, node: NodeId, tree: &Tree<T>) {
let node = node.get() as usize;
if node > self.next {
if node > self.end {
self.end = self.next;
self.back_advance = 0;
pub fn len(&self) -> usize {
self.end - self.next
}
pub fn rev<T>(self, tree: &Tree<T>) -> RevTreeIter {
let mut count = self.next - self.node;
let mut iter = RevTreeIter {
next: self.node,
end: self.node,
started: false,
};
while count > 0 {
count -= 1;
iter.next(tree);
}
iter
}
}
pub(super) struct RevTreeIter {
next: usize,
end: usize,
started: bool,
}
impl RevTreeIter {
/// for a tree (a(a.a, a.b, a.c), b)
/// yield [b, a, a.c, a.b, a.a]
pub fn next<T>(&mut self, tree: &Tree<T>) -> Option<NodeId> {
if self.next != self.end || !self.started {
self.started = true;
let next = NodeId::new(self.next);
let node = &tree.nodes[self.next];
if let Some(last_child) = node.last_child {
self.next = last_child.get();
} else if let Some(prev) = node.prev_sibling {
self.next = prev.get();
} else {
let node_ref = &tree.nodes[node];
let mut exit = node_ref;
self.back_advance = 0;
while let Some(p) = exit.parent {
self.back_advance += 1;
exit = &tree.nodes[p.get()];
if exit.descendants_end as usize >= self.end {
let mut node = node;
while let Some(parent) = node.parent {
let parent = parent.get();
if parent == self.end {
self.next = self.end;
break;
}
node = &tree.nodes[parent];
if let Some(prev) = node.prev_sibling {
self.next = prev.get();
break;
}
}
}
self.end = node_ref.descendants_end as usize;
self.next_back = node;
Some(next)
} else {
None
}
}
/// Skip to the next sibling of the node last yielded by `next`.
pub fn close<T>(&mut self, tree: &Tree<T>, yielded: NodeId) {
let mut node = &tree.nodes[yielded.get()];
if let Some(prev) = node.prev_sibling {
self.next = prev.get();
} else {
while let Some(parent) = node.parent {
let parent = parent.get();
if parent == self.end {
self.next = self.end;
break;
}
node = &tree.nodes[parent];
if let Some(prev) = node.prev_sibling {
self.next = prev.get();
break;
}
}
}
}
pub fn len(&self) -> usize {
self.end - self.next + self.back_advance
pub fn skip_to<T>(&mut self, tree: &Tree<T>, node: NodeId) {
let node = node.get();
if node > self.end {
let root = &tree.nodes[self.end];
if node >= root.descendants_end as usize {
self.next = self.end;
} else {
self.next = node;
self.started = true;
}
}
}
}
@ -445,12 +450,12 @@ mod tests {
}
#[test]
fn iter_prev() {
fn iter_rev() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
let mut iter = tree.root().self_and_descendants().rev(&tree);
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
r.push(*tree.index(id).value());
}
@ -458,7 +463,7 @@ mod tests {
}
#[test]
fn iter_next_not_root() {
fn iter_not_root() {
let tree = iter_tree();
let mut iter = tree.root().first_child().unwrap().self_and_descendants();
@ -471,12 +476,12 @@ mod tests {
}
#[test]
fn iter_prev_not_root() {
fn iter_rev_not_root() {
let tree = iter_tree();
let mut iter = tree.root().first_child().unwrap().self_and_descendants();
let mut iter = tree.root().first_child().unwrap().self_and_descendants().rev(&tree);
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
r.push(*tree.index(id).value());
}
@ -484,11 +489,10 @@ mod tests {
}
#[test]
fn iter_next_descendants() {
fn iter_descendants() {
let tree = iter_tree();
let mut iter = tree.root().first_child().unwrap().self_and_descendants();
iter.next();
iter.next_back(&tree);
let mut r = vec![];
while let Some(id) = iter.next() {
@ -499,14 +503,13 @@ mod tests {
}
#[test]
fn iter_prev_descendants() {
fn iter_rev_descendants() {
let tree = iter_tree();
let mut iter = tree.root().first_child().unwrap().self_and_descendants();
iter.next();
iter.next_back(&tree);
let mut iter = tree.root().first_child().unwrap().self_and_descendants().rev(&tree);
iter.next(&tree);
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
r.push(*tree.index(id).value());
}
@ -532,17 +535,17 @@ mod tests {
}
#[test]
fn iter_close_back() {
fn iter_rev_close() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
let mut iter = tree.root().self_and_descendants().rev(&tree);
iter.next_back(&tree).unwrap(); // r
let b = iter.next_back(&tree).unwrap();
iter.next(&tree).unwrap(); // r
let b = iter.next(&tree).unwrap();
iter.close_back(&tree, b);
iter.close(&tree, b);
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
r.push(*tree.index(id).value());
}
@ -550,66 +553,7 @@ mod tests {
}
#[test]
fn iter_both_ends() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
let r_start = iter.next().unwrap();
let r_end = iter.next_back(&tree).unwrap();
assert_eq!(tree.index(r_start).value(), tree.index(r_end).value());
}
#[test]
fn iter_both_ends_closed_back() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
iter.next_back(&tree).unwrap(); // r
iter.next_back(&tree).unwrap(); // b
let mut r = vec![];
while let Some(id) = iter.next() {
r.push(*tree.index(id).value());
}
assert_eq!(r, vec!["r", "a", "a.a", "a.b", "a.b.a", "a.b.b", "a.c"]);
}
#[test]
fn iter_both_ends_closed_front() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
for _ in 0..["r", "a", "a.a", "a.b", "a.b.a", "a.b.b", "a.c"].len() {
iter.next().unwrap();
}
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
r.push(*tree.index(id).value());
}
assert_eq!(r, vec!["r", "b"]);
}
#[test]
fn iter_both_ends_closed_front2() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
for _ in 0..["r", "a", "a.a", "a.b", "a.b.a"].len() {
iter.next().unwrap();
}
let mut r = vec![];
while let Some(id) = iter.next_back(&tree) {
r.push(*tree.index(id).value());
}
assert_eq!(r, vec!["r", "b", "a", "a.c", "a.b", "a.b.b"]);
}
#[test]
fn skip_to() {
fn iter_skip_to() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
@ -634,21 +578,21 @@ mod tests {
}
#[test]
fn skip_back_to() {
fn iter_rev_skip_to() {
let tree = iter_tree();
let mut iter = tree.root().self_and_descendants();
let mut iter = tree.root().self_and_descendants().rev(&tree);
let mut all = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
all.push(id);
}
for (i, id) in all.iter().enumerate() {
let mut iter = tree.root().self_and_descendants();
iter.skip_back_to(*id, &tree);
let mut iter = tree.root().self_and_descendants().rev(&tree);
iter.skip_to(&tree, *id);
let mut result = vec![];
while let Some(id) = iter.next_back(&tree) {
while let Some(id) = iter.next(&tree) {
result.push(tree.nodes[id.get()].value);
}