1use crate::{
4    error::{
5        self, ErrorInfo, ParseError,
6        ParseResult::{self, *},
7        ResultExt, StreamError, Tracked,
8    },
9    lib::marker::PhantomData,
10    stream::{uncons, Stream, StreamOnce},
11    Parser,
12};
13
14#[derive(Copy, Clone)]
15pub struct Any<Input>(PhantomData<fn(Input) -> Input>);
16
17impl<Input> Parser<Input> for Any<Input>
18where
19    Input: Stream,
20{
21    type Output = Input::Token;
22    type PartialState = ();
23
24    #[inline]
25    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
26        uncons(input)
27    }
28}
29
30pub fn any<Input>() -> Any<Input>
45where
46    Input: Stream,
47{
48    Any(PhantomData)
49}
50
51#[derive(Copy, Clone)]
52pub struct Satisfy<Input, P> {
53    predicate: P,
54    _marker: PhantomData<Input>,
55}
56
57fn satisfy_impl<Input, P, R>(input: &mut Input, mut predicate: P) -> ParseResult<R, Input::Error>
58where
59    Input: Stream,
60    P: FnMut(Input::Token) -> Option<R>,
61{
62    let position = input.position();
63    match uncons(input) {
64        PeekOk(c) | CommitOk(c) => match predicate(c) {
65            Some(c) => CommitOk(c),
66            None => PeekErr(Input::Error::empty(position).into()),
67        },
68        PeekErr(err) => PeekErr(err),
69        CommitErr(err) => CommitErr(err),
70    }
71}
72
73impl<Input, P> Parser<Input> for Satisfy<Input, P>
74where
75    Input: Stream,
76    P: FnMut(Input::Token) -> bool,
77{
78    type Output = Input::Token;
79    type PartialState = ();
80
81    #[inline]
82    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
83        satisfy_impl(input, |c| {
84            if (self.predicate)(c.clone()) {
85                Some(c)
86            } else {
87                None
88            }
89        })
90    }
91}
92
93pub fn satisfy<Input, P>(predicate: P) -> Satisfy<Input, P>
105where
106    Input: Stream,
107    P: FnMut(Input::Token) -> bool,
108{
109    Satisfy {
110        predicate,
111        _marker: PhantomData,
112    }
113}
114
115#[derive(Copy, Clone)]
116pub struct SatisfyMap<Input, P> {
117    predicate: P,
118    _marker: PhantomData<Input>,
119}
120
121impl<Input, P, R> Parser<Input> for SatisfyMap<Input, P>
122where
123    Input: Stream,
124    P: FnMut(Input::Token) -> Option<R>,
125{
126    type Output = R;
127    type PartialState = ();
128    #[inline]
129    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Self::Output, Input::Error> {
130        satisfy_impl(input, &mut self.predicate)
131    }
132}
133
134pub fn satisfy_map<Input, P, R>(predicate: P) -> SatisfyMap<Input, P>
159where
160    Input: Stream,
161    P: FnMut(Input::Token) -> Option<R>,
162{
163    SatisfyMap {
164        predicate,
165        _marker: PhantomData,
166    }
167}
168
169#[derive(Copy, Clone)]
170pub struct Token<Input>
171where
172    Input: Stream,
173    Input::Token: PartialEq,
174{
175    c: Input::Token,
176    _marker: PhantomData<Input>,
177}
178
179impl<Input> Parser<Input> for Token<Input>
180where
181    Input: Stream,
182    Input::Token: PartialEq + Clone,
183{
184    type Output = Input::Token;
185    type PartialState = ();
186
187    #[inline]
188    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
189        satisfy_impl(input, |c| if c == self.c { Some(c) } else { None })
190    }
191    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
192        errors.error.add_expected(error::Token(self.c.clone()));
193    }
194}
195
196pub fn token<Input>(c: Input::Token) -> Token<Input>
209where
210    Input: Stream,
211    Input::Token: PartialEq,
212{
213    Token {
214        c,
215        _marker: PhantomData,
216    }
217}
218
219#[derive(Clone)]
220pub struct Tokens<C, E, T, Input>
221where
222    Input: Stream,
223{
224    cmp: C,
225    expected: E,
226    tokens: T,
227    _marker: PhantomData<Input>,
228}
229
230impl<Input, C, E, T> Parser<Input> for Tokens<C, E, T, Input>
231where
232    C: FnMut(T::Item, Input::Token) -> bool,
233    E: for<'s> ErrorInfo<'s, Input::Token, Input::Range>,
234    T: Clone + IntoIterator,
235    Input: Stream,
236{
237    type Output = T;
238    type PartialState = ();
239    #[inline]
240    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
241        let start = input.position();
242        let mut committed = false;
243        for c in self.tokens.clone() {
244            match crate::stream::uncons(input) {
245                CommitOk(other) | PeekOk(other) => {
246                    if !(self.cmp)(c, other.clone()) {
247                        return if committed {
248                            let mut errors = <Input as StreamOnce>::Error::from_error(
249                                start,
250                                StreamError::unexpected_token(other),
251                            );
252                            errors.add_expected(&self.expected);
253                            CommitErr(errors)
254                        } else {
255                            PeekErr(<Input as StreamOnce>::Error::empty(start).into())
256                        };
257                    }
258                    committed = true;
259                }
260                PeekErr(mut error) => {
261                    error.error.set_position(start);
262                    return if committed {
263                        CommitErr(error.error)
264                    } else {
265                        PeekErr(error)
266                    };
267                }
268                CommitErr(mut error) => {
269                    error.set_position(start);
270                    return CommitErr(error);
271                }
272            }
273        }
274        if committed {
275            CommitOk(self.tokens.clone())
276        } else {
277            PeekOk(self.tokens.clone())
278        }
279    }
280    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
281        errors.error.add_expected(&self.expected);
282    }
283}
284
285pub fn tokens<C, E, T, Input>(cmp: C, expected: E, tokens: T) -> Tokens<C, E, T, Input>
311where
312    C: FnMut(T::Item, Input::Token) -> bool,
313    T: Clone + IntoIterator,
314    Input: Stream,
315{
316    Tokens {
317        cmp,
318        expected,
319        tokens,
320        _marker: PhantomData,
321    }
322}
323
324#[derive(Clone)]
325pub struct TokensCmp<C, T, Input>
326where
327    Input: Stream,
328{
329    cmp: C,
330    tokens: T,
331    _marker: PhantomData<Input>,
332}
333
334impl<Input, C, T> Parser<Input> for TokensCmp<C, T, Input>
335where
336    C: FnMut(T::Item, Input::Token) -> bool,
337    T: Clone + IntoIterator,
338    Input: Stream,
339{
340    type Output = T;
341    type PartialState = ();
342
343    #[inline]
344    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<T, Input::Error> {
345        let start = input.position();
346        let mut committed = false;
347        for c in self.tokens.clone() {
348            match crate::stream::uncons(input) {
349                CommitOk(other) | PeekOk(other) => {
350                    if !(self.cmp)(c, other.clone()) {
351                        return if committed {
352                            let errors = <Input as StreamOnce>::Error::from_error(
353                                start,
354                                StreamError::unexpected_token(other),
355                            );
356                            CommitErr(errors)
357                        } else {
358                            PeekErr(<Input as StreamOnce>::Error::empty(start).into())
359                        };
360                    }
361                    committed = true;
362                }
363                PeekErr(mut error) => {
364                    error.error.set_position(start);
365                    return if committed {
366                        CommitErr(error.error)
367                    } else {
368                        PeekErr(error)
369                    };
370                }
371                CommitErr(mut error) => {
372                    error.set_position(start);
373                    return CommitErr(error);
374                }
375            }
376        }
377        if committed {
378            CommitOk(self.tokens.clone())
379        } else {
380            PeekOk(self.tokens.clone())
381        }
382    }
383}
384
385pub fn tokens_cmp<C, T, I>(tokens: T, cmp: C) -> TokensCmp<C, T, I>
411where
412    C: FnMut(T::Item, I::Token) -> bool,
413    T: Clone + IntoIterator,
414    I: Stream,
415{
416    TokensCmp {
417        cmp,
418        tokens,
419        _marker: PhantomData,
420    }
421}
422
423#[derive(Copy, Clone)]
424pub struct Position<Input>
425where
426    Input: Stream,
427{
428    _marker: PhantomData<Input>,
429}
430
431impl<Input> Parser<Input> for Position<Input>
432where
433    Input: Stream,
434{
435    type Output = Input::Position;
436    type PartialState = ();
437
438    #[inline]
439    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Position, Input::Error> {
440        PeekOk(input.position())
441    }
442}
443
444pub fn position<Input>() -> Position<Input>
460where
461    Input: Stream,
462{
463    Position {
464        _marker: PhantomData,
465    }
466}
467
468#[derive(Copy, Clone)]
469pub struct OneOf<T, Input>
470where
471    Input: Stream,
472{
473    tokens: T,
474    _marker: PhantomData<Input>,
475}
476
477impl<Input, T> Parser<Input> for OneOf<T, Input>
478where
479    T: Clone + IntoIterator<Item = Input::Token>,
480    Input: Stream,
481    Input::Token: PartialEq,
482{
483    type Output = Input::Token;
484    type PartialState = ();
485
486    #[inline]
487    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
488        satisfy(|c| self.tokens.clone().into_iter().any(|t| t == c)).parse_lazy(input)
489    }
490
491    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
492        for expected in self.tokens.clone() {
493            errors.error.add_expected(error::Token(expected));
494        }
495    }
496}
497
498pub fn one_of<T, Input>(tokens: T) -> OneOf<T, Input>
510where
511    T: Clone + IntoIterator,
512    Input: Stream,
513    Input::Token: PartialEq<T::Item>,
514{
515    OneOf {
516        tokens,
517        _marker: PhantomData,
518    }
519}
520
521#[derive(Copy, Clone)]
522pub struct NoneOf<T, Input>
523where
524    Input: Stream,
525{
526    tokens: T,
527    _marker: PhantomData<Input>,
528}
529
530impl<Input, T> Parser<Input> for NoneOf<T, Input>
531where
532    T: Clone + IntoIterator<Item = Input::Token>,
533    Input: Stream,
534    Input::Token: PartialEq,
535{
536    type Output = Input::Token;
537    type PartialState = ();
538
539    #[inline]
540    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<Input::Token, Input::Error> {
541        satisfy(|c| self.tokens.clone().into_iter().all(|t| t != c)).parse_lazy(input)
542    }
543}
544
545pub fn none_of<T, Input>(tokens: T) -> NoneOf<T, Input>
568where
569    T: Clone + IntoIterator,
570    Input: Stream,
571    Input::Token: PartialEq<T::Item>,
572{
573    NoneOf {
574        tokens,
575        _marker: PhantomData,
576    }
577}
578
579#[derive(Copy, Clone)]
580pub struct Value<Input, T>(T, PhantomData<fn(Input) -> Input>);
581impl<Input, T> Parser<Input> for Value<Input, T>
582where
583    Input: Stream,
584    T: Clone,
585{
586    type Output = T;
587    type PartialState = ();
588    #[inline]
589    fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<T, Input::Error> {
590        PeekOk(self.0.clone())
591    }
592}
593
594pub fn value<Input, T>(v: T) -> Value<Input, T>
607where
608    Input: Stream,
609    T: Clone,
610{
611    Value(v, PhantomData)
612}
613
614#[derive(Copy, Clone)]
615pub struct Produce<Input, F>(F, PhantomData<fn(Input) -> Input>);
616impl<Input, F, R> Parser<Input> for Produce<Input, F>
617where
618    Input: Stream,
619    F: FnMut() -> R,
620{
621    type Output = R;
622    type PartialState = ();
623    #[inline]
624    fn parse_lazy(&mut self, _: &mut Input) -> ParseResult<R, Input::Error> {
625        PeekOk((self.0)())
626    }
627}
628
629pub fn produce<Input, F, R>(f: F) -> Produce<Input, F>
643where
644    Input: Stream,
645    F: FnMut() -> R,
646{
647    Produce(f, PhantomData)
648}
649
650#[derive(Copy, Clone)]
651pub struct Eof<Input>(PhantomData<Input>);
652impl<Input> Parser<Input> for Eof<Input>
653where
654    Input: Stream,
655{
656    type Output = ();
657    type PartialState = ();
658
659    #[inline]
660    fn parse_lazy(&mut self, input: &mut Input) -> ParseResult<(), Input::Error> {
661        let before = input.checkpoint();
662        match input.uncons() {
663            Err(ref err) if err.is_unexpected_end_of_input() => PeekOk(()),
664            _ => {
665                ctry!(input.reset(before).committed());
666                PeekErr(<Input as StreamOnce>::Error::empty(input.position()).into())
667            }
668        }
669    }
670
671    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
672        errors.error.add_expected("end of input");
673    }
674}
675
676pub fn eof<Input>() -> Eof<Input>
696where
697    Input: Stream,
698{
699    Eof(PhantomData)
700}