combine/parser/
sequence.rs

1//! Combinators which take multiple parsers and applies them one after another.
2
3use crate::{
4    error::{
5        ParseError,
6        ParseResult::{self, *},
7        StreamError, Tracked,
8    },
9    lib::marker::PhantomData,
10    parser::{
11        combinator::{ignore, Ignore, Map},
12        ParseMode,
13    },
14    ErrorOffset, Parser, Stream, StreamOnce,
15};
16
17macro_rules! count {
18    () => { 0 };
19    ($f: ident) => { 1 };
20    ($f: ident, $($rest: ident),+) => { 1 + count!($($rest),*) };
21}
22
23#[doc(hidden)]
24pub struct SequenceState<T, U> {
25    pub value: Option<T>,
26    pub state: U,
27}
28
29impl<T, U: Default> Default for SequenceState<T, U> {
30    fn default() -> Self {
31        SequenceState {
32            value: None,
33            state: U::default(),
34        }
35    }
36}
37
38impl<T, U> SequenceState<T, U>
39where
40    U: Default,
41{
42    unsafe fn unwrap_value(&mut self) -> T {
43        match self.value.take() {
44            Some(t) => t,
45            None => core::hint::unreachable_unchecked(),
46        }
47    }
48}
49
50macro_rules! last_ident {
51    ($id: ident) => { $id };
52    ($id: ident, $($rest: ident),+) => { last_ident!($($rest),+) };
53}
54
55fn add_sequence_error<Input>(
56    i: &mut usize,
57    first_empty_parser: usize,
58    inner_offset: ErrorOffset,
59    err: &mut Tracked<Input::Error>,
60    parser: &mut impl Parser<Input>,
61) -> bool
62where
63    Input: Stream,
64{
65    if *i + 1 == first_empty_parser {
66        Parser::add_committed_expected_error(parser, err);
67    }
68    if *i >= first_empty_parser {
69        if err.offset <= ErrorOffset(1) {
70            // We reached the last parser we need to add errors to (and the
71            // parser that actually returned the error), use the returned
72            // offset for that parser.
73            err.offset = inner_offset;
74        }
75        Parser::add_error(parser, err);
76        if err.offset <= ErrorOffset(1) {
77            return false;
78        }
79    }
80    err.offset = ErrorOffset(err.offset.0.saturating_sub(Parser::parser_count(parser).0));
81
82    *i += 1;
83    true
84}
85
86macro_rules! tuple_parser {
87    ($partial_state: ident; $h: ident $(, $id: ident)*) => {
88        #[allow(non_snake_case)]
89        #[derive(Default)]
90        pub struct $partial_state < $h $(, $id )* > {
91            pub $h: $h,
92            $(
93                pub $id: $id,
94            )*
95            #[allow(dead_code)]
96            offset: u8,
97            _marker: PhantomData <( $h, $( $id),* )>,
98        }
99
100
101        #[allow(non_snake_case)]
102        impl<$h $(, $id)*> $partial_state<$h $(, $id)*> {
103            #[allow(dead_code)]
104            fn add_errors<Input>(
105                input: &mut Input,
106                mut err: Tracked<Input::Error>,
107                first_empty_parser: usize,
108                offset: u8,
109                $h: &mut $h $(, $id : &mut $id )*
110            ) -> ParseResult<($h::Output, $($id::Output),*), <Input as StreamOnce>::Error>
111                where Input: Stream,
112                      $h: Parser<Input>,
113                      $($id: Parser<Input>),*
114            {
115                let inner_offset = err.offset;
116                err.offset = ErrorOffset(offset);
117                if first_empty_parser != 0 {
118                    if let Ok(t) = input.uncons() {
119                        err.error.add(StreamError::unexpected_token(t));
120                    }
121
122                    #[allow(unused_assignments)]
123                    let mut i = 0;
124                    loop {
125                        if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $h) {
126                            break;
127                        }
128                        $(
129                        if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $id) {
130                            break;
131                        }
132                        )*
133                        break;
134                    }
135                    CommitErr(err.error)
136                } else {
137                    PeekErr(err)
138                }
139            }
140        }
141
142        #[allow(non_snake_case)]
143        impl <Input: Stream, $h:, $($id:),*> Parser<Input> for ($h, $($id),*)
144            where Input: Stream,
145                  $h: Parser<Input>,
146                  $($id: Parser<Input>),*
147        {
148
149            type Output = ($h::Output, $($id::Output),*);
150            type PartialState = $partial_state<
151                SequenceState<$h::Output, $h::PartialState>
152                $(, SequenceState<$id::Output, $id::PartialState>)*
153            >;
154
155            parse_mode!(Input);
156            #[inline]
157            fn parse_mode_impl<MODE>(
158                &mut self,
159                mut mode: MODE,
160                input: &mut Input,
161                state: &mut Self::PartialState,
162            ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
163            where
164                MODE: ParseMode,
165            {
166                let (ref mut $h, $(ref mut $id),*) = *self;
167                let mut first_empty_parser = 0;
168                #[allow(unused_mut)]
169                let mut current_parser = 0;
170
171                #[allow(unused_macros)]
172                macro_rules! add_errors {
173                    ($err: ident, $offset: expr) => {
174                        $partial_state::add_errors(
175                            input, $err, first_empty_parser, $offset, $h, $($id),*
176                        )
177                    }
178                }
179
180                if mode.is_first() || state.$h.value.is_none() {
181                    let temp = match $h.parse_mode(mode, input, &mut state.$h.state) {
182                        CommitOk(x) => {
183                            first_empty_parser = current_parser + 1;
184                            x
185                        }
186                        PeekErr(err) => return PeekErr(err),
187                        CommitErr(err) => return CommitErr(err),
188                        PeekOk(x) => {
189                            x
190                        }
191                    };
192                    state.offset = $h.parser_count().0.saturating_add(1);
193                    // SAFETY: must be set to avoid UB below when unwrapping
194                    state.$h.value = Some(temp);
195
196                    // Once we have successfully parsed the partial input we may resume parsing in
197                    // "first mode"
198                    mode.set_first();
199                }
200
201                $(
202                    if mode.is_first() || state.$id.value.is_none() {
203                        current_parser += 1;
204                        let before = input.checkpoint();
205                        let temp = match $id.parse_mode(mode, input, &mut state.$id.state) {
206                            CommitOk(x) => {
207                                first_empty_parser = current_parser + 1;
208                                x
209                            }
210                            PeekErr(err) => {
211                                if let Err(err) = input.reset(before) {
212                                    return if first_empty_parser != 0 {
213                                        CommitErr(err.into())
214                                    } else {
215                                        PeekErr(err.into())
216                                    };
217                                }
218                                return add_errors!(err, state.offset)
219                            }
220                            CommitErr(err) => return CommitErr(err),
221                            PeekOk(x) => {
222                                x
223                            }
224                        };
225                        state.offset = state.offset.saturating_add($id.parser_count().0);
226                        // SAFETY: must be set to avoid UB below when unwrapping
227                        state.$id.value = Some(temp);
228
229                        // Once we have successfully parsed the partial input we may resume parsing in
230                        // "first mode"
231                        mode.set_first();
232                    }
233                )*
234
235                // SAFETY: requires both $h and $id to be set, see previous SAFETY comments
236                let value = unsafe { (state.$h.unwrap_value(), $(state.$id.unwrap_value()),*) };
237                if first_empty_parser != 0 {
238                    CommitOk(value)
239                } else {
240                    PeekOk(value)
241                }
242            }
243
244            #[inline]
245            fn parser_count(&self) -> ErrorOffset {
246                let (ref $h, $(ref $id),*) = *self;
247                ErrorOffset($h.parser_count().0 $( + $id.parser_count().0)*)
248            }
249
250            #[inline]
251            fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
252                let (ref mut $h, $(ref mut $id),*) = *self;
253                let prev = errors.offset;
254                $h.add_error(errors);
255                if errors.offset <= ErrorOffset(1) {
256                    errors.offset = ErrorOffset(
257                        errors.offset.0.saturating_sub(1)
258                    );
259                    return;
260                }
261                if errors.offset == prev {
262                    errors.offset = ErrorOffset(errors.offset.0.saturating_sub($h.parser_count().0));
263                }
264
265                #[allow(dead_code)]
266                const LAST: usize = count!($($id),*);
267                #[allow(unused_mut, unused_variables)]
268                let mut i = 0;
269                $(
270                    i += 1;
271                    let prev = errors.offset;
272                    $id.add_error(errors);
273                    if errors.offset <= ErrorOffset(1) {
274                        errors.offset = ErrorOffset(
275                            errors.offset.0.saturating_sub(1)
276                        );
277                        return;
278                    }
279                    if i != LAST && errors.offset == prev {
280                        errors.offset = ErrorOffset(
281                            errors.offset.0.saturating_sub($id.parser_count().0)
282                        );
283                    }
284                )*
285            }
286
287            fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
288                #[allow(unused_variables)]
289                let (ref mut $h, $(ref mut $id),*) = *self;
290                last_ident!($h $(, $id)*).add_committed_expected_error(errors)
291            }
292        }
293    }
294}
295
296tuple_parser!(PartialState1; A);
297tuple_parser!(PartialState2; A, B);
298tuple_parser!(PartialState3; A, B, C);
299tuple_parser!(PartialState4; A, B, C, D);
300tuple_parser!(PartialState5; A, B, C, D, E);
301tuple_parser!(PartialState6; A, B, C, D, E, F);
302tuple_parser!(PartialState7; A, B, C, D, E, F, G);
303tuple_parser!(PartialState8; A, B, C, D, E, F, G, H);
304tuple_parser!(PartialState9; A, B, C, D, E, F, G, H, I);
305tuple_parser!(PartialState10; A, B, C, D, E, F, G, H, I, J);
306tuple_parser!(PartialState11; A, B, C, D, E, F, G, H, I, J, K);
307tuple_parser!(PartialState12; A, B, C, D, E, F, G, H, I, J, K, L);
308tuple_parser!(PartialState13; A, B, C, D, E, F, G, H, I, J, K, L, M);
309tuple_parser!(PartialState14; A, B, C, D, E, F, G, H, I, J, K, L, M, N);
310tuple_parser!(PartialState15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P);
311tuple_parser!(PartialState16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q);
312tuple_parser!(PartialState17; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R);
313tuple_parser!(PartialState18; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S);
314tuple_parser!(PartialState19; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T);
315tuple_parser!(PartialState20; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U);
316
317#[macro_export]
318#[doc(hidden)]
319macro_rules! seq_parser_expr {
320    (; $($tt: tt)*) => {
321        ( $($tt)* )
322    };
323    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
324        $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
325    };
326    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
327        $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
328    };
329    ( (_ : $first_parser: expr ); $($tt: tt)*) => {
330        ( $($tt)* $first_parser, )
331    };
332    ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
333        $crate::seq_parser_expr!(; $($tt)* $first_parser,)
334    };
335    ( (_ : $first_parser: expr, ); $($tt: tt)*) => {
336        ( $($tt)* $first_parser, )
337    };
338    ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
339        $crate::seq_parser_expr!(; $($tt)* $first_parser,)
340    };
341}
342
343#[macro_export]
344#[doc(hidden)]
345macro_rules! seq_parser_pattern {
346    (; $($tt: tt)*) => {
347       ( $($tt)* )
348    };
349    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
350        $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* _, )
351    };
352    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
353        $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* $first_field, )
354    };
355    ( ( _ : $first_parser: expr ); $($tt: tt)*) => {
356        $crate::seq_parser_pattern!(; $($tt)* _, )
357    };
358    ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
359        $crate::seq_parser_pattern!(; $($tt)* $first_field,)
360    };
361    ( ( _ : $first_parser: expr, ); $($tt: tt)*) => {
362        $crate::seq_parser_pattern!(; $($tt)* _, )
363    };
364    ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
365        $crate::seq_parser_pattern!(; $($tt)* $first_field,)
366    };
367}
368
369#[macro_export]
370#[doc(hidden)]
371macro_rules! seq_parser_impl {
372    (; $name: ident $($tt: tt)*) => {
373        $name { $($tt)* }
374    };
375    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $name: ident $($tt: tt)*) => {
376        $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* )
377    };
378    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ );
379        $name: ident $($tt: tt)*) =>
380    {
381        $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* $first_field: $first_field, )
382    };
383    ( ( _ : $first_parser: expr ); $name: ident $($tt: tt)*) => {
384        $crate::seq_parser_impl!( ; $name $($tt)* )
385    };
386    ( ($first_field: ident : $first_parser: expr ); $name: ident $($tt: tt)*) => {
387        $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
388    };
389    ( ( _ : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
390        $crate::seq_parser_impl!(; $name $($tt)*)
391    };
392    ( ($first_field: ident : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
393        $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
394    };
395}
396
397#[macro_export]
398#[doc(hidden)]
399macro_rules! seq_tuple_extract {
400    (; ; $name: ident ;  $($arg: expr),* $(,)? ) => {
401        $name( $($arg,)* )
402    };
403
404    ( (_ : $first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
405        $crate::seq_tuple_extract!( ( $($remaining)+ ); ( $($arg),* ) ; $($tt)* )
406    };
407
408    ( ($first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
409        $crate::seq_tuple_extract!( ( $($remaining)+ ) ; ( $($arg),* ) ; $($tt)* $first_arg, )
410    };
411
412    ( (_ : $first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
413        $crate::seq_tuple_extract!(; ; $($tt)*)
414    };
415
416    ( ($first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
417        $crate::seq_tuple_extract!(; ; $($tt)* $first_arg)
418    };
419}
420
421#[macro_export]
422#[doc(hidden)]
423macro_rules! seq_tuple_parser_impl {
424    (; $($tt: tt)*) => {
425        ($($tt)*)
426    };
427
428    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
429        $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
430    };
431
432    ( ($first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
433        $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
434    };
435
436    ( (_ : $first_parser: expr $(,)? ); $($tt: tt)*) => {
437        $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
438    };
439
440    ( ($first_parser: expr $(,)? ); $($tt: tt)*) => {
441        $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
442    };
443}
444
445/// Sequences multiple parsers and builds a struct out of them.
446///
447/// ```
448/// use combine::{Parser, between, from_str, many, struct_parser, token};
449/// use combine::parser::range::take_while1;
450/// use combine::parser::byte::{letter, spaces};
451///
452/// #[derive(Debug, PartialEq)]
453/// struct Point(u32, u32);
454///
455/// #[derive(Debug, PartialEq)]
456/// struct Field {
457///     name: Vec<u8>,
458///     value: Vec<u8>,
459///     point: Point,
460/// }
461/// fn main() {
462///     let num = || from_str(take_while1(|b: u8| b >= b'0' && b <= b'9'));
463///     let spaced = |b| between(spaces(), spaces(), token(b));
464///     let mut parser = struct_parser!{
465///         Field {
466///             name: many(letter()),
467///             // `_` fields are ignored when building the struct
468///             _: spaced(b':'),
469///             value: many(letter()),
470///             _: spaced(b':'),
471///             point: struct_parser!(Point(num(), _: spaced(b','), num())),
472///         }
473///     };
474///     assert_eq!(
475///         parser.parse(&b"test: data: 123 , 4"[..]),
476///         Ok((
477///             Field {
478///                 name: b"test"[..].to_owned(),
479///                 value: b"data"[..].to_owned(),
480///                 point: Point(123, 4),
481///             },
482///             &b""[..]
483///         )),
484///     );
485/// }
486/// ```
487#[macro_export]
488macro_rules! struct_parser {
489    ($name: ident { $($tt: tt)* }) => {
490        $crate::seq_parser_expr!( ( $($tt)* ); )
491            .map(|$crate::seq_parser_pattern!( ( $($tt)* ); )|
492                $crate::seq_parser_impl!(( $($tt)* ); $name )
493            )
494    };
495
496    ($name: ident ( $($arg: tt)* )) => {
497        $crate::seq_tuple_parser_impl!( ( $($arg)* ) ; )
498            .map(|t|
499                $crate::seq_tuple_extract!(
500                    ( $($arg)* );
501                    (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, t.8, t.9, t.10, t.11, t.12, t.13, t.14);
502                    $name ;
503                )
504            )
505    }
506}
507
508#[derive(Copy, Clone)]
509pub struct With<P1, P2>((Ignore<P1>, P2));
510impl<Input, P1, P2> Parser<Input> for With<P1, P2>
511where
512    Input: Stream,
513    P1: Parser<Input>,
514    P2: Parser<Input>,
515{
516    type Output = P2::Output;
517    type PartialState = <(Ignore<P1>, P2) as Parser<Input>>::PartialState;
518
519    #[inline]
520    fn parse_lazy(
521        &mut self,
522        input: &mut Input,
523    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
524        self.0.parse_lazy(input).map(|(_, b)| b)
525    }
526
527    parse_mode!(Input);
528    #[inline]
529    fn parse_mode_impl<M>(
530        &mut self,
531        mode: M,
532        input: &mut Input,
533        state: &mut Self::PartialState,
534    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
535    where
536        M: ParseMode,
537    {
538        self.0.parse_mode(mode, input, state).map(|(_, b)| b)
539    }
540
541    forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
542}
543
544/// Equivalent to [`p1.with(p2)`].
545///
546/// [`p1.with(p2)`]: ../trait.Parser.html#method.with
547pub fn with<Input, P1, P2>(p1: P1, p2: P2) -> With<P1, P2>
548where
549    Input: Stream,
550    P1: Parser<Input>,
551    P2: Parser<Input>,
552{
553    With((ignore(p1), p2))
554}
555
556#[derive(Copy, Clone)]
557pub struct Skip<P1, P2>((P1, Ignore<P2>));
558impl<Input, P1, P2> Parser<Input> for Skip<P1, P2>
559where
560    Input: Stream,
561    P1: Parser<Input>,
562    P2: Parser<Input>,
563{
564    type Output = P1::Output;
565    type PartialState = <(P1, Ignore<P2>) as Parser<Input>>::PartialState;
566
567    parse_mode!(Input);
568    #[inline]
569    fn parse_mode_impl<M>(
570        &mut self,
571        mode: M,
572        input: &mut Input,
573        state: &mut Self::PartialState,
574    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
575    where
576        M: ParseMode,
577    {
578        self.0.parse_mode(mode, input, state).map(|(a, _)| a)
579    }
580
581    forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
582}
583
584pub fn skip<Input, P1, P2>(p1: P1, p2: P2) -> Skip<P1, P2>
585where
586    Input: Stream,
587    P1: Parser<Input>,
588    P2: Parser<Input>,
589{
590    Skip((p1, ignore(p2)))
591}
592
593parser! {
594    #[derive(Copy, Clone)]
595    pub struct Between;
596    type PartialState = <Map<(L, P, R), fn ((L::Output, P::Output, R::Output)) -> P::Output> as Parser<Input>>::PartialState;
597/// Parses `open` followed by `parser` followed by `close`.
598/// Returns the value of `parser`.
599///
600/// ```
601/// # extern crate combine;
602/// # use combine::*;
603/// # use combine::parser::char::string;
604/// # fn main() {
605/// let result = between(token('['), token(']'), string("rust"))
606///     .parse("[rust]")
607///     .map(|x| x.0);
608/// assert_eq!(result, Ok("rust"));
609/// # }
610/// ```
611pub fn between[Input, L, R, P](open: L, close: R, parser: P)(Input) -> P::Output
612where [
613    Input: Stream,
614    L: Parser< Input>,
615    R: Parser< Input>,
616    P: Parser< Input>,
617]
618{
619    fn middle<T, U, V>((_, x, _): (T, U, V)) -> U {
620        x
621    }
622    (open, parser, close).map(middle)
623}
624}
625
626#[derive(Copy, Clone)]
627pub struct Then<P, F>(P, F);
628impl<Input, P, N, F> Parser<Input> for Then<P, F>
629where
630    Input: Stream,
631    F: FnMut(P::Output) -> N,
632    P: Parser<Input>,
633    N: Parser<Input>,
634{
635    type Output = N::Output;
636    type PartialState = (P::PartialState, Option<(bool, N)>, N::PartialState);
637
638    parse_mode!(Input);
639    #[inline]
640    fn parse_mode_impl<M>(
641        &mut self,
642        mut mode: M,
643        input: &mut Input,
644        state: &mut Self::PartialState,
645    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
646    where
647        M: ParseMode,
648    {
649        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
650
651        if mode.is_first() || n_parser_cache.is_none() {
652            debug_assert!(n_parser_cache.is_none());
653
654            let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
655                PeekOk(value) => (value, false),
656                CommitOk(value) => (value, true),
657
658                PeekErr(err) => return PeekErr(err),
659                CommitErr(err) => return CommitErr(err),
660            };
661
662            *n_parser_cache = Some((committed, (self.1)(value)));
663            mode.set_first();
664        }
665
666        let result = n_parser_cache
667            .as_mut()
668            .unwrap()
669            .1
670            .parse_committed_mode(mode, input, n_state);
671        match result {
672            PeekOk(x) => {
673                let (committed, _) = *n_parser_cache.as_ref().unwrap();
674                *n_parser_cache = None;
675                if committed {
676                    CommitOk(x)
677                } else {
678                    PeekOk(x)
679                }
680            }
681            CommitOk(x) => {
682                *n_parser_cache = None;
683                CommitOk(x)
684            }
685            PeekErr(x) => {
686                let (committed, _) = *n_parser_cache.as_ref().unwrap();
687                *n_parser_cache = None;
688                if committed {
689                    CommitErr(x.error)
690                } else {
691                    PeekErr(x)
692                }
693            }
694            CommitErr(x) => CommitErr(x),
695        }
696    }
697
698    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
699        self.0.add_error(errors);
700    }
701}
702
703/// Equivalent to [`p.then(f)`].
704///
705/// [`p.then(f)`]: ../trait.Parser.html#method.then
706pub fn then<Input, P, F, N>(p: P, f: F) -> Then<P, F>
707where
708    Input: Stream,
709    F: FnMut(P::Output) -> N,
710    P: Parser<Input>,
711    N: Parser<Input>,
712{
713    Then(p, f)
714}
715
716#[derive(Copy, Clone)]
717pub struct ThenPartial<P, F>(P, F);
718impl<Input, P, N, F> Parser<Input> for ThenPartial<P, F>
719where
720    Input: Stream,
721    F: FnMut(&mut P::Output) -> N,
722    P: Parser<Input>,
723    N: Parser<Input>,
724{
725    type Output = N::Output;
726    type PartialState = (P::PartialState, Option<(bool, P::Output)>, N::PartialState);
727
728    parse_mode!(Input);
729    #[inline]
730    fn parse_mode_impl<M>(
731        &mut self,
732        mut mode: M,
733        input: &mut Input,
734        state: &mut Self::PartialState,
735    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
736    where
737        M: ParseMode,
738    {
739        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
740
741        if mode.is_first() || n_parser_cache.is_none() {
742            debug_assert!(n_parser_cache.is_none());
743
744            match self.0.parse_mode(mode, input, p_state) {
745                PeekOk(value) => {
746                    *n_parser_cache = Some((false, value));
747                }
748                CommitOk(value) => {
749                    *n_parser_cache = Some((true, value));
750                }
751                PeekErr(err) => return PeekErr(err),
752                CommitErr(err) => return CommitErr(err),
753            }
754            mode.set_first();
755        }
756
757        let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1)
758            .parse_committed_mode(mode, input, n_state);
759        match result {
760            PeekOk(x) => {
761                let (committed, _) = n_parser_cache.take().unwrap();
762                if committed {
763                    CommitOk(x)
764                } else {
765                    PeekOk(x)
766                }
767            }
768            CommitOk(x) => {
769                *n_parser_cache = None;
770                CommitOk(x)
771            }
772            PeekErr(x) => {
773                let (committed, _) = n_parser_cache.take().unwrap();
774                if committed {
775                    CommitErr(x.error)
776                } else {
777                    PeekErr(x)
778                }
779            }
780            CommitErr(x) => CommitErr(x),
781        }
782    }
783
784    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
785        self.0.add_error(errors);
786    }
787}
788
789/// Equivalent to [`p.then_partial(f)`].
790///
791/// [`p.then_partial(f)`]: ../trait.Parser.html#method.then_partial
792pub fn then_partial<Input, P, F, N>(p: P, f: F) -> ThenPartial<P, F>
793where
794    Input: Stream,
795    F: FnMut(&mut P::Output) -> N,
796    P: Parser<Input>,
797    N: Parser<Input>,
798{
799    ThenPartial(p, f)
800}
801
802#[cfg(all(feature = "std", test))]
803mod tests {
804
805    use crate::parser::{token::any, EasyParser};
806
807    #[test]
808    fn sequence_single_parser() {
809        assert!((any(),).easy_parse("a").is_ok());
810    }
811}
812
813#[derive(Copy, Clone)]
814pub struct ThenRef<P, F>(P, F);
815impl<Input, P, N, F> Parser<Input> for ThenRef<P, F>
816where
817    Input: Stream,
818    F: FnMut(&P::Output) -> N,
819    P: Parser<Input>,
820    N: Parser<Input>,
821{
822    type Output = (P::Output, N::Output);
823    type PartialState = (
824        P::PartialState,
825        Option<(bool, P::Output, N)>,
826        N::PartialState,
827    );
828
829    parse_mode!(Input);
830    #[inline]
831    fn parse_mode_impl<M>(
832        &mut self,
833        mut mode: M,
834        input: &mut Input,
835        state: &mut Self::PartialState,
836    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
837    where
838        M: ParseMode,
839    {
840        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;
841
842        if mode.is_first() || n_parser_cache.is_none() {
843            debug_assert!(n_parser_cache.is_none());
844
845            let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
846                PeekOk(value) => (value, false),
847                CommitOk(value) => (value, true),
848
849                PeekErr(err) => return PeekErr(err),
850                CommitErr(err) => return CommitErr(err),
851            };
852
853            let parser = (self.1)(&value);
854            *n_parser_cache = Some((committed, value, parser));
855
856            mode.set_first();
857        }
858
859        let result = n_parser_cache
860            .as_mut()
861            .unwrap()
862            .2
863            .parse_committed_mode(mode, input, n_state);
864        match result {
865            PeekOk(x) => {
866                let (committed, in_value, _) = n_parser_cache.take().unwrap();
867                if committed {
868                    CommitOk((in_value, x))
869                } else {
870                    PeekOk((in_value, x))
871                }
872            }
873            CommitOk(x) => {
874                let (_, in_value, _) = n_parser_cache.take().unwrap();
875                *n_parser_cache = None;
876                CommitOk((in_value, x))
877            }
878            PeekErr(x) => {
879                let (committed, _, _) = n_parser_cache.take().unwrap();
880                *n_parser_cache = None;
881                if committed {
882                    CommitErr(x.error)
883                } else {
884                    PeekErr(x)
885                }
886            }
887            CommitErr(x) => CommitErr(x),
888        }
889    }
890
891    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
892        self.0.add_error(errors);
893    }
894}
895
896/// Equivalent to [`p.then_ref(f)`].
897///
898/// [`p.then_ref(f)`]: ../trait.Parser.html#method.then
899pub fn then_ref<Input, P, F, N>(p: P, f: F) -> ThenRef<P, F>
900where
901    Input: Stream,
902    F: FnMut(&P::Output) -> N,
903    P: Parser<Input>,
904    N: Parser<Input>,
905{
906    ThenRef(p, f)
907}