diff options
Diffstat (limited to 'src/components/util/tree.rs')
-rw-r--r-- | src/components/util/tree.rs | 24 |
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) |