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}