1use crate::{
2 error::{ParseError, ParseResult, StreamError},
3 lib::fmt,
4 stream::{
5 IteratorStream, Positioned, RangeStreamOnce, ResetStream, SliceStream, StreamErrorFor,
6 StreamOnce,
7 },
8};
9
10#[cfg(feature = "std")]
11use crate::stream::read;
12
13pub trait Positioner<Item> {
15 type Position: Clone + Ord;
17
18 type Checkpoint: Clone;
19
20 fn position(&self) -> Self::Position;
22 fn update(&mut self, token: &Item);
24
25 fn checkpoint(&self) -> Self::Checkpoint;
26 fn reset(&mut self, checkpoint: Self::Checkpoint);
27}
28
29pub trait RangePositioner<Item, Range>: Positioner<Item> {
31 fn update_range(&mut self, range: &Range);
33}
34
35pub trait DefaultPositioned {
37 type Positioner: Default;
38}
39
40impl<'a> DefaultPositioned for &'a str {
41 type Positioner = SourcePosition;
42}
43
44impl<'a, T> DefaultPositioned for &'a [T] {
45 type Positioner = IndexPositioner;
46}
47
48impl<'a, T> DefaultPositioned for SliceStream<'a, T> {
49 type Positioner = IndexPositioner;
50}
51
52impl<T> DefaultPositioned for IteratorStream<T> {
53 type Positioner = IndexPositioner;
54}
55
56#[cfg(feature = "std")]
57impl<R> DefaultPositioned for read::Stream<R> {
58 type Positioner = IndexPositioner;
59}
60
61#[derive(Clone, Debug, PartialEq)]
85pub struct Stream<Input, X> {
86 pub input: Input,
88 pub positioner: X,
90}
91
92impl<Input, X> Stream<Input, X>
93where
94 Input: StreamOnce,
95 X: Positioner<Input::Token>,
96{
97 pub fn with_positioner(input: Input, positioner: X) -> Stream<Input, X> {
99 Stream { input, positioner }
100 }
101}
102
103impl<Input> Stream<Input, Input::Positioner>
104where
105 Input: StreamOnce + DefaultPositioned,
106 Input::Positioner: Positioner<Input::Token>,
107{
108 pub fn new(input: Input) -> Stream<Input, Input::Positioner> {
110 Stream::with_positioner(input, Input::Positioner::default())
111 }
112}
113
114impl<Input, X, S> Positioned for Stream<Input, X>
115where
116 Input: StreamOnce,
117 X: Positioner<Input::Token>,
118 S: StreamError<Input::Token, Input::Range>,
119 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
120 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
121{
122 #[inline]
123 fn position(&self) -> Self::Position {
124 self.positioner.position()
125 }
126}
127
128impl<Input, X, S> StreamOnce for Stream<Input, X>
129where
130 Input: StreamOnce,
131 X: Positioner<Input::Token>,
132 S: StreamError<Input::Token, Input::Range>,
133 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
134 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
135{
136 type Token = Input::Token;
137 type Range = Input::Range;
138 type Position = X::Position;
139 type Error = Input::Error;
140
141 #[inline]
142 fn uncons(&mut self) -> Result<Input::Token, StreamErrorFor<Self>> {
143 self.input.uncons().map(|c| {
144 self.positioner.update(&c);
145 c
146 })
147 }
148
149 fn is_partial(&self) -> bool {
150 self.input.is_partial()
151 }
152}
153
154impl<Item, T> Positioner<Item> for &'_ mut T
155where
156 Item: Clone,
157 T: ?Sized + Positioner<Item>,
158{
159 type Position = T::Position;
160 type Checkpoint = T::Checkpoint;
161
162 #[inline]
163 fn position(&self) -> T::Position {
164 (**self).position()
165 }
166
167 #[inline]
168 fn update(&mut self, item: &Item) {
169 (**self).update(item)
170 }
171
172 #[inline]
173 fn checkpoint(&self) -> Self::Checkpoint {
174 (**self).checkpoint()
175 }
176
177 #[inline]
178 fn reset(&mut self, checkpoint: Self::Checkpoint) {
179 (**self).reset(checkpoint)
180 }
181}
182
183impl<Item, Range, T> RangePositioner<Item, Range> for &'_ mut T
184where
185 Item: Clone,
186 Range: Clone + crate::stream::Range,
187 T: ?Sized + RangePositioner<Item, Range>,
188{
189 fn update_range(&mut self, range: &Range) {
190 (**self).update_range(range);
191 }
192}
193
194#[derive(Clone, Debug, Default, PartialEq)]
198pub struct IndexPositioner(usize);
199
200impl<Item> Positioner<Item> for IndexPositioner
201where
202 Item: Clone,
203{
204 type Position = usize;
205 type Checkpoint = Self;
206
207 #[inline]
208 fn position(&self) -> usize {
209 self.0
210 }
211
212 #[inline]
213 fn update(&mut self, _item: &Item) {
214 self.0 += 1
215 }
216
217 #[inline]
218 fn checkpoint(&self) -> Self::Checkpoint {
219 self.clone()
220 }
221
222 #[inline]
223 fn reset(&mut self, checkpoint: Self::Checkpoint) {
224 *self = checkpoint;
225 }
226}
227
228impl IndexPositioner {
229 pub fn new() -> IndexPositioner {
230 IndexPositioner::new_with_position(0)
231 }
232
233 pub fn new_with_position(position: usize) -> IndexPositioner {
234 IndexPositioner(position)
235 }
236}
237
238impl<Item, Range> RangePositioner<Item, Range> for IndexPositioner
239where
240 Item: Clone,
241 Range: Clone + crate::stream::Range,
242{
243 fn update_range(&mut self, range: &Range) {
244 self.0 += range.len()
245 }
246}
247
248#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
250pub struct SourcePosition {
251 pub line: i32,
253 pub column: i32,
255}
256
257impl Default for SourcePosition {
258 fn default() -> Self {
259 SourcePosition { line: 1, column: 1 }
260 }
261}
262
263impl fmt::Display for SourcePosition {
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 write!(f, "line: {}, column: {}", self.line, self.column)
266 }
267}
268
269impl SourcePosition {
270 pub fn new() -> Self {
271 SourcePosition::default()
272 }
273}
274
275impl Positioner<char> for SourcePosition {
276 type Position = SourcePosition;
277 type Checkpoint = Self;
278
279 #[inline]
280 fn position(&self) -> SourcePosition {
281 *self
282 }
283
284 #[inline]
285 fn update(&mut self, token: &char) {
286 self.column += 1;
287 if *token == '\n' {
288 self.column = 1;
289 self.line += 1;
290 }
291 }
292
293 #[inline]
294 fn checkpoint(&self) -> Self::Checkpoint {
295 *self
296 }
297
298 #[inline]
299 fn reset(&mut self, checkpoint: Self::Checkpoint) {
300 *self = checkpoint;
301 }
302}
303
304impl Positioner<u8> for SourcePosition {
305 type Position = SourcePosition;
306 type Checkpoint = Self;
307
308 #[inline]
309 fn position(&self) -> SourcePosition {
310 *self
311 }
312
313 #[inline]
314 fn update(&mut self, token: &u8) {
315 self.column += 1;
316 if *token == b'\n' {
317 self.column = 1;
318 self.line += 1;
319 }
320 }
321
322 #[inline]
323 fn checkpoint(&self) -> Self::Checkpoint {
324 *self
325 }
326
327 #[inline]
328 fn reset(&mut self, checkpoint: Self::Checkpoint) {
329 *self = checkpoint;
330 }
331}
332
333impl<'a> RangePositioner<char, &'a str> for SourcePosition {
334 fn update_range(&mut self, range: &&'a str) {
335 for c in range.chars() {
336 self.update(&c);
337 }
338 }
339}
340
341impl<Input, X, S> RangeStreamOnce for Stream<Input, X>
342where
343 Input: RangeStreamOnce,
344 X: RangePositioner<Input::Token, Input::Range>,
345 S: StreamError<Input::Token, Input::Range>,
346 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
347 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
348 Input::Position: Clone + Ord,
349{
350 #[inline]
351 fn uncons_range(&mut self, size: usize) -> Result<Input::Range, StreamErrorFor<Self>> {
352 self.input.uncons_range(size).map(|range| {
353 self.positioner.update_range(&range);
354 range
355 })
356 }
357
358 #[inline]
359 fn uncons_while<F>(&mut self, mut predicate: F) -> Result<Input::Range, StreamErrorFor<Self>>
360 where
361 F: FnMut(Input::Token) -> bool,
362 {
363 let positioner = &mut self.positioner;
364 self.input.uncons_while(|t| {
365 if predicate(t.clone()) {
366 positioner.update(&t);
367 true
368 } else {
369 false
370 }
371 })
372 }
373
374 #[inline]
375 fn uncons_while1<F>(
376 &mut self,
377 mut predicate: F,
378 ) -> ParseResult<Self::Range, StreamErrorFor<Self>>
379 where
380 F: FnMut(Self::Token) -> bool,
381 {
382 let positioner = &mut self.positioner;
383 self.input.uncons_while1(|t| {
384 if predicate(t.clone()) {
385 positioner.update(&t);
386 true
387 } else {
388 false
389 }
390 })
391 }
392
393 #[inline]
394 fn distance(&self, end: &Self::Checkpoint) -> usize {
395 self.input.distance(&end.input)
396 }
397
398 fn range(&self) -> Self::Range {
399 self.input.range()
400 }
401}
402
403impl<Input, X, S> ResetStream for Stream<Input, X>
404where
405 Input: ResetStream,
406 X: Positioner<Input::Token>,
407 S: StreamError<Input::Token, Input::Range>,
408 Input::Error: ParseError<Input::Token, Input::Range, X::Position, StreamError = S>,
409 Input::Error: ParseError<Input::Token, Input::Range, Input::Position, StreamError = S>,
410{
411 type Checkpoint = Stream<Input::Checkpoint, X::Checkpoint>;
412 fn checkpoint(&self) -> Self::Checkpoint {
413 Stream {
414 input: self.input.checkpoint(),
415 positioner: self.positioner.checkpoint(),
416 }
417 }
418 fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
419 self.input.reset(checkpoint.input)?;
420 self.positioner.reset(checkpoint.positioner);
421 Ok(())
422 }
423}
424
425#[cfg(all(feature = "std", test))]
426mod tests {
427
428 use crate::Parser;
429
430 use super::*;
431
432 #[test]
433 fn test_positioner() {
434 let input = ["a".to_string(), "b".to_string()];
435 let mut parser = crate::any();
436 let result = parser.parse(Stream::new(&input[..]));
437 assert_eq!(
438 result,
439 Ok((
440 "a".to_string(),
441 Stream::with_positioner(
442 &["b".to_string()][..],
443 IndexPositioner::new_with_position(1)
444 )
445 ))
446 );
447 }
448
449 #[test]
450 fn test_range_positioner() {
451 let input = ["a".to_string(), "b".to_string(), "c".to_string()];
452 let mut parser = crate::parser::range::take(2);
453 let result = parser.parse(Stream::new(&input[..]));
454 assert_eq!(
455 result,
456 Ok((
457 &["a".to_string(), "b".to_string()][..],
458 Stream::with_positioner(
459 &["c".to_string()][..],
460 IndexPositioner::new_with_position(2)
461 )
462 ))
463 );
464 }
465}