1use std::fmt::Debug;
2
3use crate::input::{Input, Show, Rewind, ParserInfo, Length};
4
5#[derive(Debug)]
6pub struct Cursor<T> {
7 pub start: T,
8 pub items: T,
9}
10
11impl<T: Copy> From<T> for Cursor<T> {
12 fn from(items: T) -> Self {
13 Cursor { start: items, items }
14 }
15}
16
17#[derive(Debug, PartialEq, Eq, Copy, Clone)]
18pub struct Extent<T> {
19 pub start: usize,
20 pub end: usize,
21 pub values: T,
22}
23
24impl<T: Length> From<T> for Extent<T> {
25 fn from(values: T) -> Self {
26 Extent { start: 0, end: values.len(), values }
27 }
28}
29
30impl<T> std::ops::Deref for Extent<T> {
31 type Target = T;
32
33 fn deref(&self) -> &Self::Target {
34 &self.values
35 }
36}
37
38impl<T: PartialEq> PartialEq<T> for Extent<T> {
39 fn eq(&self, other: &T) -> bool {
40 &self.values == other
41 }
42}
43
44impl PartialEq<Extent<&str>> for &str {
45 fn eq(&self, other: &Extent<&str>) -> bool {
46 other == self
47 }
48}
49
50impl<T: PartialEq> PartialEq<Extent<&[T]>> for &[T] {
51 fn eq(&self, other: &Extent<&[T]>) -> bool {
52 other == self
53 }
54}
55
56macro_rules! impl_for_slice_len {
57 ($($n:expr),*) => ($(
58 impl<T: PartialEq> PartialEq<Extent<&[T]>> for &[T; $n] {
59 fn eq(&self, other: &Extent<&[T]>) -> bool {
60 &other.values[..] == *self
61 }
62 }
63 )*)
64}
65
66impl_for_slice_len!(
67 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
68 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
69);
70
71impl<T> Length for Extent<T> {
72 fn len(&self) -> usize {
73 self.end - self.start
74 }
75}
76
77impl<T: Show> Show for Extent<T> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 write!(f, "{}..{} {}", self.start, self.end, &self.values as &dyn Show)
80 }
81}
82
83impl<T: ?Sized + ToOwned> Extent<&T> {
84 pub fn into_owned(self) -> Extent<T::Owned> {
85 Extent {
86 start: self.start,
87 end: self.end,
88 values: self.values.to_owned(),
89 }
90 }
91}
92
93pub trait Indexable: Sized {
94 type One: Clone;
95 type Iter: Iterator<Item = Self::One>;
96
97 fn head(&self) -> Option<Self::One>;
98 fn length_of(token: Self::One) -> usize;
99 fn slice<R: std::ops::RangeBounds<usize>>(&self, range: R) -> Option<Self>;
100 fn iter(&self) -> Self::Iter;
101}
102
103use std::ops::{Bound, RangeBounds, Range};
104
105fn abs<R: RangeBounds<usize>>(range: R, start: usize, end: usize) -> Range<usize> {
106 let start = match range.start_bound() {
107 Bound::Unbounded => start,
108 Bound::Included(&n) => n,
109 Bound::Excluded(&n) => n.saturating_add(1),
110 };
111
112 let end = match range.end_bound() {
113 Bound::Unbounded => end,
114 Bound::Included(&n) => n.saturating_add(1),
115 Bound::Excluded(&n) => n,
116 };
117
118 Range { start, end }
119}
120
121impl<'a> Indexable for &'a str {
122 type One = char;
123 type Iter = std::str::Chars<'a>;
124
125 fn head(&self) -> Option<Self::One> {
126 self.chars().next()
127 }
128
129 fn length_of(token: Self::One) -> usize {
130 token.len_utf8()
131 }
132
133 fn slice<R: std::ops::RangeBounds<usize>>(&self, range: R) -> Option<Self> {
134 self.get(abs(range, 0, self.len()))
135 }
136
137 fn iter(&self) -> Self::Iter {
138 self.chars()
139 }
140}
141
142impl<'a, T: Clone> Indexable for &'a [T] {
143 type One = T;
144 type Iter = std::iter::Cloned<std::slice::Iter<'a, T>>;
145
146 fn head(&self) -> Option<Self::One> {
147 self.first().cloned()
148 }
149
150 fn length_of(_: Self::One) -> usize {
151 1
152 }
153
154 fn slice<R: std::ops::RangeBounds<usize>>(&self, range: R) -> Option<Self> {
155 self.get(abs(range, 0, self.len()))
156 }
157
158 fn iter(&self) -> Self::Iter {
159 (*self as &[T]).iter().cloned()
160 }
161}
162
163impl<T: Length> Cursor<T> {
164 fn offset(&self) -> usize {
165 self.start.len() - self.items.len()
166 }
167}
168
169impl<T: Indexable + Length> Cursor<T> {
170 pub fn span(&self, a: Extent<T>, b: Extent<T>) -> Option<Extent<T>> {
172 let start = std::cmp::min(a.start, b.start);
173 let end = std::cmp::max(a.end, b.end);
174 let values = self.start.slice(start..end)?;
175 Some(Extent { start, end, values })
176 }
177}
178
179impl<T: Indexable + Show + Length + PartialEq> Input for Cursor<T>
180 where T::One: Show + PartialEq
181{
182 type Token = T::One;
183 type Slice = Extent<T>;
184 type Many = Extent<T>;
185
186 type Marker = usize;
187 type Context = Extent<T>;
188
189 fn token(&mut self) -> Option<Self::Token> {
191 self.items.head()
192 }
193
194 fn slice(&mut self, n: usize) -> Option<Self::Slice> {
196 Some(Extent {
197 start: self.offset(),
198 end: self.offset() + n,
199 values: self.items.slice(..n)?
200 })
201 }
202
203 fn peek<F>(&mut self, mut cond: F) -> bool
205 where F: FnMut(&Self::Token) -> bool
206 {
207 self.token().map(|t| cond(&t)).unwrap_or(false)
208 }
209
210 fn peek_slice<F>(&mut self, n: usize, mut cond: F) -> bool
212 where F: FnMut(&Self::Slice) -> bool
213 {
214 self.slice(n).map(|s| cond(&s)).unwrap_or(false)
215 }
216
217 fn eat<F>(&mut self, mut cond: F) -> Option<Self::Token>
220 where F: FnMut(&Self::Token) -> bool
221 {
222 let token = self.token()?;
223 if cond(&token) {
224 self.items = self.items.slice(T::length_of(token.clone())..).unwrap();
225 Some(token)
226 } else {
227 None
228 }
229 }
230
231 fn eat_slice<F>(&mut self, n: usize, mut cond: F) -> Option<Self::Slice>
234 where F: FnMut(&Self::Slice) -> bool
235 {
236 let slice = self.slice(n)?;
237 if cond(&slice) {
238 self.items = self.items.slice(n..).unwrap();
239 Some(slice)
240 } else {
241 None
242 }
243 }
244
245 fn take<F>(&mut self, cond: F) -> Self::Many
248 where F: FnMut(&Self::Token) -> bool
249 {
250 let start = self.offset();
251 let matches: usize = self.items.iter()
252 .take_while(cond)
253 .map(T::length_of)
254 .sum();
255
256 let values = self.items.slice(..matches).unwrap();
257 self.items = self.items.slice(matches..).unwrap();
258 Extent { start, end: self.offset(), values }
259 }
260
261 fn skip<F>(&mut self, cond: F) -> usize
264 where F: FnMut(&Self::Token) -> bool
265 {
266 self.take(cond).len()
267 }
268
269 fn has(&mut self, n: usize) -> bool {
271 self.items.len() >= n
272 }
273
274 fn mark(&mut self, _: &ParserInfo) -> Self::Marker {
275 self.offset()
276 }
277
278 fn context(&mut self, mark: Self::Marker) -> Self::Context {
282 let end = self.offset();
283 let values = self.start.slice(mark..end).unwrap();
284 Extent { start: mark, end, values }
285 }
286}
287
288impl<T: Indexable + Show + Length + PartialEq> Rewind for Cursor<T>
289 where T::One: Show + PartialEq
290{
291 fn rewind_to(&mut self, marker: Self::Marker) {
292 self.items = self.start.slice(marker..).unwrap();
293 }
294}