aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/util/tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/util/tree.rs')
-rw-r--r--src/components/util/tree.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/components/util/tree.rs b/src/components/util/tree.rs
index d38d4a7f5da..2b3b467ac45 100644
--- a/src/components/util/tree.rs
+++ b/src/components/util/tree.rs
@@ -42,6 +42,23 @@ impl<Node, Ref: TreeNodeRef<Node>> Iterator<Ref> for ChildIterator<Ref> {
}
}
+pub struct AncestorIterator<Ref> {
+ priv current: Option<Ref>,
+}
+
+impl<Node, Ref: TreeNodeRef<Node>> Iterator<Ref> for AncestorIterator<Ref> {
+ fn next(&mut self) -> Option<Ref> {
+ if self.current.is_none() {
+ return None;
+ }
+
+ // FIXME: Do we need two clones here?
+ let x = self.current.get_ref().clone();
+ self.current = x.with_base(|n| TreeNodeRef::<Node>::parent_node(n));
+ Some(x.clone())
+ }
+}
+
// FIXME: Do this without precomputing a vector of refs.
// Easy for preorder; harder for postorder.
pub struct TreeIterator<Ref> {
@@ -196,6 +213,13 @@ pub trait TreeNodeRef<Node>: Clone {
}
}
+ /// Iterates over all ancestors of this node.
+ fn ancestors(&self) -> AncestorIterator<Self> {
+ AncestorIterator {
+ current: self.with_base(|n| get!(n, parent_node)),
+ }
+ }
+
/// Iterates over this node and all its descendants, in preorder.
fn traverse_preorder(&self) -> TreeIterator<Self> {
self.traverse_preorder_prune(|_| false)