From efd96e8df6805a45aaf5822141dee11c642b51ae Mon Sep 17 00:00:00 2001 From: Akshay Date: Tue, 2 Aug 2022 16:57:04 +0530 Subject: init --- src/traverse.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/traverse.rs (limited to 'src/traverse.rs') diff --git a/src/traverse.rs b/src/traverse.rs new file mode 100644 index 0000000..df13f5d --- /dev/null +++ b/src/traverse.rs @@ -0,0 +1,51 @@ +// Lazy pre-order traversal over arbitrary tree-sitter trees + +// extern +use tree_sitter::{Node, Tree, TreeCursor}; + +pub struct PreOrder<'a> { + cursor: TreeCursor<'a>, + done: bool, +} + +impl<'a> PreOrder<'a> { + pub fn new(tree: &'a Tree) -> Self { + Self { + cursor: tree.walk(), + done: false, + } + } +} + +// Traverse the tree in root-left-right fashion +impl<'a> Iterator for PreOrder<'a> { + type Item = Node<'a>; + + fn next(&mut self) -> Option { + if self.done { + return None; + } + + // capture the root node + let node = self.cursor.node(); + + // if this node has a child, move there and return the root, or + // if this node has a sibling, move there and return the root + if self.cursor.goto_first_child() || self.cursor.goto_next_sibling() { + return Some(node); + } + + loop { + // we are done retracing all the way back to the root node + if !self.cursor.goto_parent() { + self.done = true; + break; + } + + if self.cursor.goto_next_sibling() { + break; + } + } + Some(node) + } +} -- cgit v1.2.3