1use core::{
2 fmt, mem,
3 ops::{AddAssign, Deref},
4};
5
6use crate::TextSize;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum NodeOrToken<N, T> {
10 Node(N),
11 Token(T),
12}
13
14impl<N, T> NodeOrToken<N, T> {
15 pub fn into_node(self) -> Option<N> {
16 match self {
17 NodeOrToken::Node(node) => Some(node),
18 NodeOrToken::Token(_) => None,
19 }
20 }
21
22 pub fn into_token(self) -> Option<T> {
23 match self {
24 NodeOrToken::Node(_) => None,
25 NodeOrToken::Token(token) => Some(token),
26 }
27 }
28
29 pub fn as_node(&self) -> Option<&N> {
30 match self {
31 NodeOrToken::Node(node) => Some(node),
32 NodeOrToken::Token(_) => None,
33 }
34 }
35
36 pub fn as_token(&self) -> Option<&T> {
37 match self {
38 NodeOrToken::Node(_) => None,
39 NodeOrToken::Token(token) => Some(token),
40 }
41 }
42}
43
44impl<N: Deref, T: Deref> NodeOrToken<N, T> {
45 pub(crate) fn as_deref(&self) -> NodeOrToken<&N::Target, &T::Target> {
46 match self {
47 NodeOrToken::Node(node) => NodeOrToken::Node(node),
48 NodeOrToken::Token(token) => NodeOrToken::Token(token),
49 }
50 }
51}
52
53impl<N: fmt::Display, T: fmt::Display> fmt::Display for NodeOrToken<N, T> {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 match self {
56 NodeOrToken::Node(node) => fmt::Display::fmt(node, f),
57 NodeOrToken::Token(token) => fmt::Display::fmt(token, f),
58 }
59 }
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
63pub enum Direction {
64 Next,
65 Prev,
66}
67
68#[derive(Debug, Copy, Clone)]
70pub enum WalkEvent<T> {
71 Enter(T),
73 Leave(T),
75}
76
77impl<T> WalkEvent<T> {
78 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> WalkEvent<U> {
79 match self {
80 WalkEvent::Enter(it) => WalkEvent::Enter(f(it)),
81 WalkEvent::Leave(it) => WalkEvent::Leave(f(it)),
82 }
83 }
84}
85
86#[derive(Clone, Debug)]
88pub enum TokenAtOffset<T> {
89 None,
91 Single(T),
93 Between(T, T),
95}
96
97impl<T> TokenAtOffset<T> {
98 pub fn map<F: Fn(T) -> U, U>(self, f: F) -> TokenAtOffset<U> {
99 match self {
100 TokenAtOffset::None => TokenAtOffset::None,
101 TokenAtOffset::Single(it) => TokenAtOffset::Single(f(it)),
102 TokenAtOffset::Between(l, r) => TokenAtOffset::Between(f(l), f(r)),
103 }
104 }
105
106 pub fn right_biased(self) -> Option<T> {
108 match self {
109 TokenAtOffset::None => None,
110 TokenAtOffset::Single(node) => Some(node),
111 TokenAtOffset::Between(_, right) => Some(right),
112 }
113 }
114
115 pub fn left_biased(self) -> Option<T> {
117 match self {
118 TokenAtOffset::None => None,
119 TokenAtOffset::Single(node) => Some(node),
120 TokenAtOffset::Between(left, _) => Some(left),
121 }
122 }
123}
124
125impl<T> Iterator for TokenAtOffset<T> {
126 type Item = T;
127
128 fn next(&mut self) -> Option<T> {
129 match mem::replace(self, TokenAtOffset::None) {
130 TokenAtOffset::None => None,
131 TokenAtOffset::Single(node) => {
132 *self = TokenAtOffset::None;
133 Some(node)
134 }
135 TokenAtOffset::Between(left, right) => {
136 *self = TokenAtOffset::Single(right);
137 Some(left)
138 }
139 }
140 }
141
142 fn size_hint(&self) -> (usize, Option<usize>) {
143 match self {
144 TokenAtOffset::None => (0, Some(0)),
145 TokenAtOffset::Single(_) => (1, Some(1)),
146 TokenAtOffset::Between(_, _) => (2, Some(2)),
147 }
148 }
149}
150
151impl<T> ExactSizeIterator for TokenAtOffset<T> {}
152
153#[derive(Copy, Clone, Debug)]
154pub(crate) enum Delta<T> {
155 Add(T),
156 Sub(T),
157}
158
159macro_rules! impls {
162 ($($ty:ident)*) => {$(
163 impl AddAssign<Delta<$ty>> for $ty {
164 fn add_assign(&mut self, rhs: Delta<$ty>) {
165 match rhs {
166 Delta::Add(amt) => *self += amt,
167 Delta::Sub(amt) => *self -= amt,
168 }
169 }
170 }
171 )*};
172}
173impls!(u32 TextSize);