rslint_rowan/
utility_types.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2pub enum NodeOrToken<N, T> {
3    Node(N),
4    Token(T),
5}
6
7impl<N, T> NodeOrToken<N, T> {
8    pub fn into_node(self) -> Option<N> {
9        match self {
10            NodeOrToken::Node(node) => Some(node),
11            NodeOrToken::Token(_) => None,
12        }
13    }
14
15    pub fn into_token(self) -> Option<T> {
16        match self {
17            NodeOrToken::Node(_) => None,
18            NodeOrToken::Token(token) => Some(token),
19        }
20    }
21
22    pub fn as_node(&self) -> Option<&N> {
23        match self {
24            NodeOrToken::Node(node) => Some(node),
25            NodeOrToken::Token(_) => None,
26        }
27    }
28
29    pub fn as_token(&self) -> Option<&T> {
30        match self {
31            NodeOrToken::Node(_) => None,
32            NodeOrToken::Token(token) => Some(token),
33        }
34    }
35
36    pub(crate) fn as_ref(&self) -> NodeOrToken<&N, &T> {
37        match self {
38            NodeOrToken::Node(node) => NodeOrToken::Node(node),
39            NodeOrToken::Token(token) => NodeOrToken::Token(token),
40        }
41    }
42}
43
44impl<N: Clone, T: Clone> NodeOrToken<&N, &T> {
45    pub(crate) fn cloned(&self) -> NodeOrToken<N, T> {
46        match *self {
47            NodeOrToken::Node(node) => NodeOrToken::Node(node.clone()),
48            NodeOrToken::Token(token) => NodeOrToken::Token(token.clone()),
49        }
50    }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub enum Direction {
55    Next,
56    Prev,
57}
58
59/// `WalkEvent` describes tree walking process.
60#[derive(Debug, Copy, Clone)]
61pub enum WalkEvent<T> {
62    /// Fired before traversing the node.
63    Enter(T),
64    /// Fired after the node is traversed.
65    Leave(T),
66}
67
68impl<T> WalkEvent<T> {
69    pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> WalkEvent<U> {
70        match self {
71            WalkEvent::Enter(it) => WalkEvent::Enter(f(it)),
72            WalkEvent::Leave(it) => WalkEvent::Leave(f(it)),
73        }
74    }
75}
76
77/// There might be zero, one or two leaves at a given offset.
78#[derive(Clone, Debug)]
79pub enum TokenAtOffset<T> {
80    /// No leaves at offset -- possible for the empty file.
81    None,
82    /// Only a single leaf at offset.
83    Single(T),
84    /// Offset is exactly between two leaves.
85    Between(T, T),
86}
87
88impl<T> TokenAtOffset<T> {
89    pub fn map<F: Fn(T) -> U, U>(self, f: F) -> TokenAtOffset<U> {
90        match self {
91            TokenAtOffset::None => TokenAtOffset::None,
92            TokenAtOffset::Single(it) => TokenAtOffset::Single(f(it)),
93            TokenAtOffset::Between(l, r) => TokenAtOffset::Between(f(l), f(r)),
94        }
95    }
96
97    /// Convert to option, preferring the right leaf in case of a tie.
98    pub fn right_biased(self) -> Option<T> {
99        match self {
100            TokenAtOffset::None => None,
101            TokenAtOffset::Single(node) => Some(node),
102            TokenAtOffset::Between(_, right) => Some(right),
103        }
104    }
105
106    /// Convert to option, preferring the left leaf in case of a tie.
107    pub fn left_biased(self) -> Option<T> {
108        match self {
109            TokenAtOffset::None => None,
110            TokenAtOffset::Single(node) => Some(node),
111            TokenAtOffset::Between(left, _) => Some(left),
112        }
113    }
114}
115
116impl<T> Iterator for TokenAtOffset<T> {
117    type Item = T;
118
119    fn next(&mut self) -> Option<T> {
120        match std::mem::replace(self, TokenAtOffset::None) {
121            TokenAtOffset::None => None,
122            TokenAtOffset::Single(node) => {
123                *self = TokenAtOffset::None;
124                Some(node)
125            }
126            TokenAtOffset::Between(left, right) => {
127                *self = TokenAtOffset::Single(right);
128                Some(left)
129            }
130        }
131    }
132
133    fn size_hint(&self) -> (usize, Option<usize>) {
134        match self {
135            TokenAtOffset::None => (0, Some(0)),
136            TokenAtOffset::Single(_) => (1, Some(1)),
137            TokenAtOffset::Between(_, _) => (2, Some(2)),
138        }
139    }
140}
141
142impl<T> ExactSizeIterator for TokenAtOffset<T> {}