Skip to main content

regast_syntax/
cursor.rs

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}