//! Combinators which take multiple parsers and applies them one after another.

use crate::{
    error::{
        ParseError,
        ParseResult::{self, *},
        StreamError, Tracked,
    },
    lib::marker::PhantomData,
    parser::{
        combinator::{ignore, Ignore, Map},
        ParseMode,
    },
    ErrorOffset, Parser, Stream, StreamOnce,
};

macro_rules! dispatch_on {
    ($i: expr, $f: expr;) => {
    };
    ($i: expr, $f: expr; $first: ident $(, $id: ident)*) => { {
        let b = $f($i, $first);
        if b {
            dispatch_on!($i + 1, $f; $($id),*);
        }
    } }
}

macro_rules! count {
    () => { 0 };
    ($f: ident) => { 1 };
    ($f: ident, $($rest: ident),+) => { 1 + count!($($rest),*) };
}

#[doc(hidden)]
pub struct SequenceState<T, U> {
    pub value: Option<T>,
    pub state: U,
}

impl<T, U: Default> Default for SequenceState<T, U> {
    fn default() -> Self {
        SequenceState {
            value: None,
            state: U::default(),
        }
    }
}

impl<T, U> SequenceState<T, U>
where
    U: Default,
{
    unsafe fn unwrap_value(&mut self) -> T {
        match self.value.take() {
            Some(t) => t,
            None => core::hint::unreachable_unchecked(),
        }
    }
}

macro_rules! last_ident {
    ($id: ident) => { $id };
    ($id: ident, $($rest: ident),+) => { last_ident!($($rest),+) };
}

macro_rules! tuple_parser {
    ($partial_state: ident; $h: ident $(, $id: ident)*) => {
        #[allow(non_snake_case)]
        #[derive(Default)]
        pub struct $partial_state < $h $(, $id )* > {
            pub $h: $h,
            $(
                pub $id: $id,
            )*
            #[allow(dead_code)]
            offset: u8,
            _marker: PhantomData <( $h, $( $id),* )>,
        }


        #[allow(non_snake_case)]
        impl<$h $(, $id)*> $partial_state<$h $(, $id)*> {
            #[allow(dead_code)]
            fn add_errors<Input>(
                input: &mut Input,
                mut err: Tracked<Input::Error>,
                first_empty_parser: usize,
                offset: u8,
                $h: &mut $h $(, $id : &mut $id )*
            ) -> ParseResult<($h::Output, $($id::Output),*), <Input as StreamOnce>::Error>
                where Input: Stream,
                      Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
                      $h: Parser<Input>,
                      $($id: Parser<Input>),*
            {
                let inner_offset = err.offset;
                err.offset = ErrorOffset(offset);
                if first_empty_parser != 0 {
                    if let Ok(t) = input.uncons() {
                        err.error.add(StreamError::unexpected_token(t));
                    }
                    dispatch_on!(0, |i, mut p| {
                        if i + 1 == first_empty_parser {
                            Parser::add_committed_expected_error(&mut p, &mut err);
                        }
                        if i >= first_empty_parser {
                            if err.offset <= ErrorOffset(1) {
                                // We reached the last parser we need to add errors to (and the
                                // parser that actually returned the error), use the returned
                                // offset for that parser.
                                err.offset = inner_offset;
                            }
                            Parser::add_error(&mut p, &mut err);
                            if err.offset <= ErrorOffset(1) {
                                return false;
                            }
                        }
                        err.offset = ErrorOffset(
                            err.offset.0.saturating_sub(Parser::parser_count(&p).0)
                        );
                        true
                    }; $h $(, $id)*);
                    CommitErr(err.error)
                } else {
                    PeekErr(err)
                }
            }
        }

        #[allow(non_snake_case)]
        impl <Input: Stream, $h:, $($id:),*> Parser<Input> for ($h, $($id),*)
            where Input: Stream,
                  Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
                  $h: Parser<Input>,
                  $($id: Parser<Input>),*
        {

            type Output = ($h::Output, $($id::Output),*);
            type PartialState = $partial_state<
                SequenceState<$h::Output, $h::PartialState>
                $(, SequenceState<$id::Output, $id::PartialState>)*
            >;

            parse_mode!(Input);
            #[inline]
            fn parse_mode_impl<MODE>(
                &mut self,
                mut mode: MODE,
                input: &mut Input,
                state: &mut Self::PartialState,
            ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
            where
                MODE: ParseMode,
            {
                let (ref mut $h, $(ref mut $id),*) = *self;
                let mut first_empty_parser = 0;
                #[allow(unused_mut)]
                let mut current_parser = 0;

                #[allow(unused_macros)]
                macro_rules! add_errors {
                    ($err: ident, $offset: expr) => {
                        $partial_state::add_errors(
                            input, $err, first_empty_parser, $offset, $h, $($id),*
                        )
                    }
                }

                if mode.is_first() || state.$h.value.is_none() {
                    let temp = match $h.parse_mode(mode, input, &mut state.$h.state) {
                        CommitOk(x) => {
                            first_empty_parser = current_parser + 1;
                            x
                        }
                        PeekErr(err) => return PeekErr(err),
                        CommitErr(err) => return CommitErr(err),
                        PeekOk(x) => {
                            x
                        }
                    };
                    state.offset = $h.parser_count().0.saturating_add(1);
                    // SAFETY: must be set to avoid UB below when unwrapping
                    state.$h.value = Some(temp);

                    // Once we have successfully parsed the partial input we may resume parsing in
                    // "first mode"
                    mode.set_first();
                }

                $(
                    if mode.is_first() || state.$id.value.is_none() {
                        current_parser += 1;
                        let before = input.checkpoint();
                        let temp = match $id.parse_mode(mode, input, &mut state.$id.state) {
                            CommitOk(x) => {
                                first_empty_parser = current_parser + 1;
                                x
                            }
                            PeekErr(err) => {
                                if let Err(err) = input.reset(before) {
                                    return if first_empty_parser != 0 {
                                        CommitErr(err.into())
                                    } else {
                                        PeekErr(err.into())
                                    };
                                }
                                return add_errors!(err, state.offset)
                            }
                            CommitErr(err) => return CommitErr(err),
                            PeekOk(x) => {
                                x
                            }
                        };
                        state.offset = state.offset.saturating_add($id.parser_count().0);
                        // SAFETY: must be set to avoid UB below when unwrapping
                        state.$id.value = Some(temp);

                        // Once we have successfully parsed the partial input we may resume parsing in
                        // "first mode"
                        mode.set_first();
                    }
                )*

                // SAFETY: requires both $h and $id to be set, see previous SAFETY comments
                let value = unsafe { (state.$h.unwrap_value(), $(state.$id.unwrap_value()),*) };
                if first_empty_parser != 0 {
                    CommitOk(value)
                } else {
                    PeekOk(value)
                }
            }

            #[inline]
            fn parser_count(&self) -> ErrorOffset {
                let (ref $h, $(ref $id),*) = *self;
                ErrorOffset($h.parser_count().0 $( + $id.parser_count().0)*)
            }

            #[inline]
            fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
                let (ref mut $h, $(ref mut $id),*) = *self;
                let prev = errors.offset;
                $h.add_error(errors);
                if errors.offset <= ErrorOffset(1) {
                    errors.offset = ErrorOffset(
                        errors.offset.0.saturating_sub(1)
                    );
                    return;
                }
                if errors.offset == prev {
                    errors.offset = ErrorOffset(errors.offset.0.saturating_sub($h.parser_count().0));
                }

                #[allow(dead_code)]
                const LAST: usize = count!($($id),*);
                #[allow(unused_mut, unused_variables)]
                let mut i = 0;
                $(
                    i += 1;
                    let prev = errors.offset;
                    $id.add_error(errors);
                    if errors.offset <= ErrorOffset(1) {
                        errors.offset = ErrorOffset(
                            errors.offset.0.saturating_sub(1)
                        );
                        return;
                    }
                    if i != LAST && errors.offset == prev {
                        errors.offset = ErrorOffset(
                            errors.offset.0.saturating_sub($id.parser_count().0)
                        );
                    }
                )*
            }

            fn add_committed_expected_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
                #[allow(unused_variables)]
                let (ref mut $h, $(ref mut $id),*) = *self;
                last_ident!($h $(, $id)*).add_committed_expected_error(errors)
            }
        }
    }
}

tuple_parser!(PartialState1; A);
tuple_parser!(PartialState2; A, B);
tuple_parser!(PartialState3; A, B, C);
tuple_parser!(PartialState4; A, B, C, D);
tuple_parser!(PartialState5; A, B, C, D, E);
tuple_parser!(PartialState6; A, B, C, D, E, F);
tuple_parser!(PartialState7; A, B, C, D, E, F, G);
tuple_parser!(PartialState8; A, B, C, D, E, F, G, H);
tuple_parser!(PartialState9; A, B, C, D, E, F, G, H, I);
tuple_parser!(PartialState10; A, B, C, D, E, F, G, H, I, J);
tuple_parser!(PartialState11; A, B, C, D, E, F, G, H, I, J, K);
tuple_parser!(PartialState12; A, B, C, D, E, F, G, H, I, J, K, L);
tuple_parser!(PartialState13; A, B, C, D, E, F, G, H, I, J, K, L, M);
tuple_parser!(PartialState14; A, B, C, D, E, F, G, H, I, J, K, L, M, N);
tuple_parser!(PartialState15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P);
tuple_parser!(PartialState16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q);
tuple_parser!(PartialState17; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R);
tuple_parser!(PartialState18; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S);
tuple_parser!(PartialState19; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T);
tuple_parser!(PartialState20; A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q, R, S, T, U);

#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_expr {
    (; $($tt: tt)*) => {
        ( $($tt)* )
    };
    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
    };
    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_parser_expr!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
    };
    ( (_ : $first_parser: expr ); $($tt: tt)*) => {
        ( $($tt)* $first_parser, )
    };
    ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
        $crate::seq_parser_expr!(; $($tt)* $first_parser,)
    };
    ( (_ : $first_parser: expr, ); $($tt: tt)*) => {
        ( $($tt)* $first_parser, )
    };
    ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
        $crate::seq_parser_expr!(; $($tt)* $first_parser,)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_pattern {
    (; $($tt: tt)*) => {
       ( $($tt)* )
    };
    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* _, )
    };
    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!( ( $($remaining)+ ) ; $($tt)* $first_field, )
    };
    ( ( _ : $first_parser: expr ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!(; $($tt)* _, )
    };
    ( ($first_field: ident : $first_parser: expr ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!(; $($tt)* $first_field,)
    };
    ( ( _ : $first_parser: expr, ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!(; $($tt)* _, )
    };
    ( ($first_field: ident : $first_parser: expr, ); $($tt: tt)*) => {
        $crate::seq_parser_pattern!(; $($tt)* $first_field,)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! seq_parser_impl {
    (; $name: ident $($tt: tt)*) => {
        $name { $($tt)* }
    };
    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $name: ident $($tt: tt)*) => {
        $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* )
    };
    ( ($first_field: ident : $first_parser: expr, $($remaining: tt)+ );
        $name: ident $($tt: tt)*) =>
    {
        $crate::seq_parser_impl!( ( $($remaining)+ ) ; $name $($tt)* $first_field: $first_field, )
    };
    ( ( _ : $first_parser: expr ); $name: ident $($tt: tt)*) => {
        $crate::seq_parser_impl!( ; $name $($tt)* )
    };
    ( ($first_field: ident : $first_parser: expr ); $name: ident $($tt: tt)*) => {
        $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
    };
    ( ( _ : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
        $crate::seq_parser_impl!(; $name $($tt)*)
    };
    ( ($first_field: ident : $first_parser: expr, ); $name: ident $($tt: tt)*) => {
        $crate::seq_parser_impl!(; $name $($tt)* $first_field: $first_field,)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! seq_tuple_extract {
    (; ; $name: ident ;  $($arg: expr),* $(,)? ) => {
        $name( $($arg,)* )
    };

    ( (_ : $first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
        $crate::seq_tuple_extract!( ( $($remaining)+ ); ( $($arg),* ) ; $($tt)* )
    };

    ( ($first_parser: expr, $($remaining: tt)+ ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
        $crate::seq_tuple_extract!( ( $($remaining)+ ) ; ( $($arg),* ) ; $($tt)* $first_arg, )
    };

    ( (_ : $first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
        $crate::seq_tuple_extract!(; ; $($tt)*)
    };

    ( ($first_parser: expr $(,)? ); ( $first_arg: expr, $($arg: expr),* ) ; $($tt: tt)*) => {
        $crate::seq_tuple_extract!(; ; $($tt)* $first_arg)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! seq_tuple_parser_impl {
    (; $($tt: tt)*) => {
        ($($tt)*)
    };

    ( (_ : $first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
    };

    ( ($first_parser: expr, $($remaining: tt)+ ); $($tt: tt)*) => {
        $crate::seq_tuple_parser_impl!( ( $($remaining)+ ) ; $($tt)* $first_parser, )
    };

    ( (_ : $first_parser: expr $(,)? ); $($tt: tt)*) => {
        $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
    };

    ( ($first_parser: expr $(,)? ); $($tt: tt)*) => {
        $crate::seq_tuple_parser_impl!(; $($tt)* $first_parser, )
    };
}

/// Sequences multiple parsers and builds a struct out of them.
///
/// ```
/// use combine::{Parser, between, from_str, many, struct_parser, token};
/// use combine::parser::range::take_while1;
/// use combine::parser::byte::{letter, spaces};
///
/// #[derive(Debug, PartialEq)]
/// struct Point(u32, u32);
///
/// #[derive(Debug, PartialEq)]
/// struct Field {
///     name: Vec<u8>,
///     value: Vec<u8>,
///     point: Point,
/// }
/// fn main() {
///     let num = || from_str(take_while1(|b: u8| b >= b'0' && b <= b'9'));
///     let spaced = |b| between(spaces(), spaces(), token(b));
///     let mut parser = struct_parser!{
///         Field {
///             name: many(letter()),
///             // `_` fields are ignored when building the struct
///             _: spaced(b':'),
///             value: many(letter()),
///             _: spaced(b':'),
///             point: struct_parser!(Point(num(), _: spaced(b','), num())),
///         }
///     };
///     assert_eq!(
///         parser.parse(&b"test: data: 123 , 4"[..]),
///         Ok((
///             Field {
///                 name: b"test"[..].to_owned(),
///                 value: b"data"[..].to_owned(),
///                 point: Point(123, 4),
///             },
///             &b""[..]
///         )),
///     );
/// }
/// ```
#[macro_export]
macro_rules! struct_parser {
    ($name: ident { $($tt: tt)* }) => {
        $crate::seq_parser_expr!( ( $($tt)* ); )
            .map(|$crate::seq_parser_pattern!( ( $($tt)* ); )|
                $crate::seq_parser_impl!(( $($tt)* ); $name )
            )
    };

    ($name: ident ( $($arg: tt)* )) => {
        $crate::seq_tuple_parser_impl!( ( $($arg)* ) ; )
            .map(|t|
                $crate::seq_tuple_extract!(
                    ( $($arg)* );
                    (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);
                    $name ;
                )
            )
    }
}

#[derive(Copy, Clone)]
pub struct With<P1, P2>((Ignore<P1>, P2));
impl<Input, P1, P2> Parser<Input> for With<P1, P2>
where
    Input: Stream,
    P1: Parser<Input>,
    P2: Parser<Input>,
{
    type Output = P2::Output;
    type PartialState = <(Ignore<P1>, P2) as Parser<Input>>::PartialState;

    #[inline]
    fn parse_lazy(
        &mut self,
        input: &mut Input,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
        self.0.parse_lazy(input).map(|(_, b)| b)
    }

    parse_mode!(Input);
    #[inline]
    fn parse_mode_impl<M>(
        &mut self,
        mode: M,
        input: &mut Input,
        state: &mut Self::PartialState,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
    where
        M: ParseMode,
    {
        self.0.parse_mode(mode, input, state).map(|(_, b)| b)
    }

    forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
}

/// Equivalent to [`p1.with(p2)`].
///
/// [`p1.with(p2)`]: ../trait.Parser.html#method.with
pub fn with<Input, P1, P2>(p1: P1, p2: P2) -> With<P1, P2>
where
    Input: Stream,
    P1: Parser<Input>,
    P2: Parser<Input>,
{
    With((ignore(p1), p2))
}

#[derive(Copy, Clone)]
pub struct Skip<P1, P2>((P1, Ignore<P2>));
impl<Input, P1, P2> Parser<Input> for Skip<P1, P2>
where
    Input: Stream,
    P1: Parser<Input>,
    P2: Parser<Input>,
{
    type Output = P1::Output;
    type PartialState = <(P1, Ignore<P2>) as Parser<Input>>::PartialState;

    parse_mode!(Input);
    #[inline]
    fn parse_mode_impl<M>(
        &mut self,
        mode: M,
        input: &mut Input,
        state: &mut Self::PartialState,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
    where
        M: ParseMode,
    {
        self.0.parse_mode(mode, input, state).map(|(a, _)| a)
    }

    forward_parser!(Input, add_error add_committed_expected_error parser_count, 0);
}

pub fn skip<Input, P1, P2>(p1: P1, p2: P2) -> Skip<P1, P2>
where
    Input: Stream,
    P1: Parser<Input>,
    P2: Parser<Input>,
{
    Skip((p1, ignore(p2)))
}

parser! {
    #[derive(Copy, Clone)]
    pub struct Between;
    type PartialState = <Map<(L, P, R), fn ((L::Output, P::Output, R::Output)) -> P::Output> as Parser<Input>>::PartialState;
/// Parses `open` followed by `parser` followed by `close`.
/// Returns the value of `parser`.
///
/// ```
/// # extern crate combine;
/// # use combine::*;
/// # use combine::parser::char::string;
/// # fn main() {
/// let result = between(token('['), token(']'), string("rust"))
///     .parse("[rust]")
///     .map(|x| x.0);
/// assert_eq!(result, Ok("rust"));
/// # }
/// ```
pub fn between[Input, L, R, P](open: L, close: R, parser: P)(Input) -> P::Output
where [
    Input: Stream,
    L: Parser< Input>,
    R: Parser< Input>,
    P: Parser< Input>,
]
{
    fn middle<T, U, V>((_, x, _): (T, U, V)) -> U {
        x
    }
    (open, parser, close).map(middle)
}
}

#[derive(Copy, Clone)]
pub struct Then<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for Then<P, F>
where
    Input: Stream,
    F: FnMut(P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    type Output = N::Output;
    type PartialState = (P::PartialState, Option<(bool, N)>, N::PartialState);

    parse_mode!(Input);
    #[inline]
    fn parse_mode_impl<M>(
        &mut self,
        mut mode: M,
        input: &mut Input,
        state: &mut Self::PartialState,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
    where
        M: ParseMode,
    {
        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;

        if mode.is_first() || n_parser_cache.is_none() {
            debug_assert!(n_parser_cache.is_none());

            let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
                PeekOk(value) => (value, false),
                CommitOk(value) => (value, true),

                PeekErr(err) => return PeekErr(err),
                CommitErr(err) => return CommitErr(err),
            };

            *n_parser_cache = Some((committed, (self.1)(value)));
            mode.set_first();
        }

        let result = n_parser_cache
            .as_mut()
            .unwrap()
            .1
            .parse_committed_mode(mode, input, n_state);
        match result {
            PeekOk(x) => {
                let (committed, _) = *n_parser_cache.as_ref().unwrap();
                *n_parser_cache = None;
                if committed {
                    CommitOk(x)
                } else {
                    PeekOk(x)
                }
            }
            CommitOk(x) => {
                *n_parser_cache = None;
                CommitOk(x)
            }
            PeekErr(x) => {
                let (committed, _) = *n_parser_cache.as_ref().unwrap();
                *n_parser_cache = None;
                if committed {
                    CommitErr(x.error)
                } else {
                    PeekErr(x)
                }
            }
            CommitErr(x) => CommitErr(x),
        }
    }

    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
        self.0.add_error(errors);
    }
}

/// Equivalent to [`p.then(f)`].
///
/// [`p.then(f)`]: ../trait.Parser.html#method.then
pub fn then<Input, P, F, N>(p: P, f: F) -> Then<P, F>
where
    Input: Stream,
    F: FnMut(P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    Then(p, f)
}

#[derive(Copy, Clone)]
pub struct ThenPartial<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for ThenPartial<P, F>
where
    Input: Stream,
    F: FnMut(&mut P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    type Output = N::Output;
    type PartialState = (P::PartialState, Option<(bool, P::Output)>, N::PartialState);

    parse_mode!(Input);
    #[inline]
    fn parse_mode_impl<M>(
        &mut self,
        mut mode: M,
        input: &mut Input,
        state: &mut Self::PartialState,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
    where
        M: ParseMode,
    {
        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;

        if mode.is_first() || n_parser_cache.is_none() {
            debug_assert!(n_parser_cache.is_none());

            match self.0.parse_mode(mode, input, p_state) {
                PeekOk(value) => {
                    *n_parser_cache = Some((false, value));
                }
                CommitOk(value) => {
                    *n_parser_cache = Some((true, value));
                }
                PeekErr(err) => return PeekErr(err),
                CommitErr(err) => return CommitErr(err),
            }
            mode.set_first();
        }

        let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1)
            .parse_committed_mode(mode, input, n_state);
        match result {
            PeekOk(x) => {
                let (committed, _) = n_parser_cache.take().unwrap();
                if committed {
                    CommitOk(x)
                } else {
                    PeekOk(x)
                }
            }
            CommitOk(x) => {
                *n_parser_cache = None;
                CommitOk(x)
            }
            PeekErr(x) => {
                let (committed, _) = n_parser_cache.take().unwrap();
                if committed {
                    CommitErr(x.error)
                } else {
                    PeekErr(x)
                }
            }
            CommitErr(x) => CommitErr(x),
        }
    }

    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
        self.0.add_error(errors);
    }
}

/// Equivalent to [`p.then_partial(f)`].
///
/// [`p.then_partial(f)`]: ../trait.Parser.html#method.then_partial
pub fn then_partial<Input, P, F, N>(p: P, f: F) -> ThenPartial<P, F>
where
    Input: Stream,
    F: FnMut(&mut P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    ThenPartial(p, f)
}

#[cfg(all(feature = "std", test))]
mod tests {

    use crate::parser::{token::any, EasyParser};

    #[test]
    fn sequence_single_parser() {
        assert!((any(),).easy_parse("a").is_ok());
    }
}

#[derive(Copy, Clone)]
pub struct ThenRef<P, F>(P, F);
impl<Input, P, N, F> Parser<Input> for ThenRef<P, F>
where
    Input: Stream,
    F: FnMut(&P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    type Output = (P::Output, N::Output);
    type PartialState = (
        P::PartialState,
        Option<(bool, P::Output, N)>,
        N::PartialState,
    );

    parse_mode!(Input);
    #[inline]
    fn parse_mode_impl<M>(
        &mut self,
        mut mode: M,
        input: &mut Input,
        state: &mut Self::PartialState,
    ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
    where
        M: ParseMode,
    {
        let (ref mut p_state, ref mut n_parser_cache, ref mut n_state) = *state;

        if mode.is_first() || n_parser_cache.is_none() {
            debug_assert!(n_parser_cache.is_none());

            let (value, committed) = match self.0.parse_mode(mode, input, p_state) {
                PeekOk(value) => (value, false),
                CommitOk(value) => (value, true),

                PeekErr(err) => return PeekErr(err),
                CommitErr(err) => return CommitErr(err),
            };

            let parser = (self.1)(&value);
            *n_parser_cache = Some((committed, value, parser));

            mode.set_first();
        }

        let result = n_parser_cache
            .as_mut()
            .unwrap()
            .2
            .parse_committed_mode(mode, input, n_state);
        match result {
            PeekOk(x) => {
                let (committed, in_value, _) = n_parser_cache.take().unwrap();
                if committed {
                    CommitOk((in_value, x))
                } else {
                    PeekOk((in_value, x))
                }
            }
            CommitOk(x) => {
                let (_, in_value, _) = n_parser_cache.take().unwrap();
                *n_parser_cache = None;
                CommitOk((in_value, x))
            }
            PeekErr(x) => {
                let (committed, _, _) = n_parser_cache.take().unwrap();
                *n_parser_cache = None;
                if committed {
                    CommitErr(x.error)
                } else {
                    PeekErr(x)
                }
            }
            CommitErr(x) => CommitErr(x),
        }
    }

    fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
        self.0.add_error(errors);
    }
}

/// Equivalent to [`p.then_ref(f)`].
///
/// [`p.then_ref(f)`]: ../trait.Parser.html#method.then
pub fn then_ref<Input, P, F, N>(p: P, f: F) -> ThenRef<P, F>
where
    Input: Stream,
    F: FnMut(&P::Output) -> N,
    P: Parser<Input>,
    N: Parser<Input>,
{
    ThenRef(p, f)
}
