1use crate::{AstKind, NodeId, Pattern, Span};
2
3#[derive(Clone, Copy, Debug)]
4pub struct Cursor<'p> {
5 pat: &'p Pattern,
6 id: NodeId,
7}
8
9impl<'p> Cursor<'p> {
10 pub(crate) const fn new(pat: &'p Pattern, id: NodeId) -> Self {
11 Self { pat, id }
12 }
13
14 #[must_use]
15 pub const fn id(self) -> NodeId {
16 self.id
17 }
18
19 #[must_use]
20 pub fn kind(self) -> &'p AstKind {
21 &self.pat.node(self.id).kind
22 }
23
24 #[must_use]
25 pub fn span(self) -> Span {
26 self.pat.node(self.id).span
27 }
28
29 #[must_use]
30 pub fn text(self) -> &'p str {
31 self.pat.text(self.span())
32 }
33
34 #[must_use]
35 pub fn parent(self) -> Option<Self> {
36 self.pat
37 .node(self.id)
38 .parent
39 .map(|id| Self::new(self.pat, id))
40 }
41
42 #[must_use]
43 pub fn children(self) -> Children<'p> {
44 Children {
45 pat: self.pat,
46 inner: self.kind().children().iter(),
47 }
48 }
49
50 #[must_use]
51 pub fn next_sibling(self) -> Option<Self> {
52 self.sibling(1)
53 }
54
55 #[must_use]
56 pub fn prev_sibling(self) -> Option<Self> {
57 self.sibling(-1)
58 }
59
60 fn sibling(self, delta: isize) -> Option<Self> {
61 let parent = self.parent()?;
62 let children = parent.kind().children();
63 let index = children
64 .iter()
65 .position(|id| *id == self.id)?
66 .checked_add_signed(delta)?;
67 let id = *children.get(index)?;
68 Some(Self::new(self.pat, id))
69 }
70
71 #[must_use]
72 pub fn ancestors(self) -> Ancestors<'p> {
73 Ancestors {
74 next: self.parent(),
75 }
76 }
77
78 #[must_use]
79 pub fn walk(self) -> Walk<'p> {
80 Walk { stack: vec![self] }
81 }
82}
83
84pub struct Children<'p> {
85 pat: &'p Pattern,
86 inner: std::slice::Iter<'p, NodeId>,
87}
88
89impl<'p> Iterator for Children<'p> {
90 type Item = Cursor<'p>;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 self.inner
94 .next()
95 .copied()
96 .map(|id| Cursor::new(self.pat, id))
97 }
98}
99
100pub struct Ancestors<'p> {
101 next: Option<Cursor<'p>>,
102}
103
104impl<'p> Iterator for Ancestors<'p> {
105 type Item = Cursor<'p>;
106
107 fn next(&mut self) -> Option<Self::Item> {
108 let current = self.next?;
109 self.next = current.parent();
110 Some(current)
111 }
112}
113
114pub struct Walk<'p> {
115 stack: Vec<Cursor<'p>>,
116}
117
118impl<'p> Iterator for Walk<'p> {
119 type Item = Cursor<'p>;
120
121 fn next(&mut self) -> Option<Self::Item> {
122 let node = self.stack.pop()?;
123 self.stack.extend(node.children().rev());
124 Some(node)
125 }
126}
127
128impl DoubleEndedIterator for Children<'_> {
129 fn next_back(&mut self) -> Option<Self::Item> {
130 self.inner
131 .next_back()
132 .copied()
133 .map(|id| Cursor::new(self.pat, id))
134 }
135}