1use crate::{Leaf, Subtree, TokenTree, TokenTreesView};
5
6pub struct Cursor<'a, Span> {
7 buffer: &'a [TokenTree<Span>],
8 index: usize,
9 subtrees_stack: Vec<usize>,
10}
11
12impl<'a, Span: Copy> Cursor<'a, Span> {
13 pub fn new(buffer: &'a [TokenTree<Span>]) -> Self {
14 Self { buffer, index: 0, subtrees_stack: Vec::new() }
15 }
16
17 pub fn eof(&self) -> bool {
19 self.index == self.buffer.len() && self.subtrees_stack.is_empty()
20 }
21
22 pub fn is_root(&self) -> bool {
23 self.subtrees_stack.is_empty()
24 }
25
26 fn last_subtree(&self) -> Option<(usize, &'a Subtree<Span>)> {
27 self.subtrees_stack.last().map(|&subtree_idx| {
28 let TokenTree::Subtree(subtree) = &self.buffer[subtree_idx] else {
29 panic!("subtree pointing to non-subtree");
30 };
31 (subtree_idx, subtree)
32 })
33 }
34
35 pub fn end(&mut self) -> &'a Subtree<Span> {
36 let (last_subtree_idx, last_subtree) =
37 self.last_subtree().expect("called `Cursor::end()` without an open subtree");
38 assert_eq!(
40 last_subtree_idx + last_subtree.usize_len() + 1,
41 self.index,
42 "called `Cursor::end()` without finishing a subtree"
43 );
44 self.subtrees_stack.pop();
45 last_subtree
46 }
47
48 pub fn token_tree(&self) -> Option<&'a TokenTree<Span>> {
50 if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() {
51 if last_subtree_idx + last_subtree.usize_len() + 1 == self.index {
53 return None;
54 }
55 }
56 self.buffer.get(self.index)
57 }
58
59 pub fn bump(&mut self) {
61 if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() {
62 assert_ne!(
64 last_subtree_idx + last_subtree.usize_len() + 1,
65 self.index,
66 "called `Cursor::bump()` when at the end of a subtree"
67 );
68 }
69 if let TokenTree::Subtree(_) = self.buffer[self.index] {
70 self.subtrees_stack.push(self.index);
71 }
72 self.index += 1;
73 }
74
75 pub fn bump_or_end(&mut self) {
76 if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() {
77 if last_subtree_idx + last_subtree.usize_len() + 1 == self.index {
79 self.subtrees_stack.pop();
80 return;
81 }
82 }
83 if let TokenTree::Subtree(_) = self.buffer[self.index] {
85 self.subtrees_stack.push(self.index);
86 }
87 self.index += 1;
88 }
89
90 pub fn peek_two_leaves(&self) -> Option<[&'a Leaf<Span>; 2]> {
91 if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() {
92 let last_end = last_subtree_idx + last_subtree.usize_len() + 1;
94 if last_end == self.index || last_end == self.index + 1 {
95 return None;
96 }
97 }
98 self.buffer.get(self.index..self.index + 2).and_then(|it| match it {
99 [TokenTree::Leaf(a), TokenTree::Leaf(b)] => Some([a, b]),
100 _ => None,
101 })
102 }
103
104 pub fn crossed(&self) -> TokenTreesView<'a, Span> {
105 assert!(self.is_root());
106 TokenTreesView::new(&self.buffer[..self.index])
107 }
108}