use crate::{
error::{
ParseError,
ParseResult::{self, *},
StreamError, Tracked,
},
lib::marker::PhantomData,
parser::{
combinator::{ignore, Ignore, Map},
ParseMode,
},
ErrorOffset, Parser, Stream, StreamOnce,
};
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),+) };
}
fn add_sequence_error<Input>(
i: &mut usize,
first_empty_parser: usize,
inner_offset: ErrorOffset,
err: &mut Tracked<Input::Error>,
parser: &mut impl Parser<Input>,
) -> bool
where
Input: Stream,
{
if *i + 1 == first_empty_parser {
Parser::add_committed_expected_error(parser, err);
}
if *i >= first_empty_parser {
if err.offset <= ErrorOffset(1) {
err.offset = inner_offset;
}
Parser::add_error(parser, err);
if err.offset <= ErrorOffset(1) {
return false;
}
}
err.offset = ErrorOffset(err.offset.0.saturating_sub(Parser::parser_count(parser).0));
*i += 1;
true
}
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,
$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));
}
#[allow(unused_assignments)]
let mut i = 0;
loop {
if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $h) {
break;
}
$(
if !add_sequence_error(&mut i, first_empty_parser, inner_offset, &mut err, $id) {
break;
}
)*
break;
}
CommitErr(err.error)
} else {
PeekErr(err)
}
}
}
#[allow(non_snake_case)]
impl <Input: Stream, $h:, $($id:),*> Parser<Input> for ($h, $($id),*)
where Input: Stream,
$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);
state.$h.value = Some(temp);
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);
state.$id.value = Some(temp);
mode.set_first();
}
)*
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, )
};
}
#[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);
}
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;
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);
}
}
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);
}
}
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);
}
}
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)
}