diff --git a/src/ascii/mod.rs b/src/ascii/mod.rs index aefa647b..be423c87 100644 --- a/src/ascii/mod.rs +++ b/src/ascii/mod.rs @@ -56,7 +56,7 @@ where I: Stream, I: Compare<&'static str>, { - trace("crlf", move |input: I| "\r\n".parse_peek(input)).parse_peek(input) + trace("crlf", "\r\n").parse_peek(input) } /// Recognizes a string of any char except '\r\n' or '\n'. @@ -183,10 +183,7 @@ where I: Stream, I: Compare<&'static str>, { - trace("line_ending", move |input: I| { - alt(("\n", "\r\n")).parse_peek(input) - }) - .parse_peek(input) + trace("line_ending", alt(("\n", "\r\n"))).parse_peek(input) } /// Matches a newline character '\n'. @@ -224,11 +221,7 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("newline", move |input: I| { - '\n'.map(|c: ::Token| c.as_char()) - .parse_peek(input) - }) - .parse_peek(input) + trace("newline", '\n'.map(|c: ::Token| c.as_char())).parse_peek(input) } /// Matches a tab character '\t'. @@ -266,11 +259,7 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("tab", move |input: I| { - '\t'.map(|c: ::Token| c.as_char()) - .parse_peek(input) - }) - .parse_peek(input) + trace("tab", '\t'.map(|c: ::Token| c.as_char())).parse_peek(input) } /// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z @@ -310,9 +299,10 @@ where I: Stream, ::Token: AsChar, { - trace("alpha0", move |input: I| { - take_while(0.., |c: ::Token| c.is_alpha()).parse_peek(input) - }) + trace( + "alpha0", + take_while(0.., |c: ::Token| c.is_alpha()), + ) .parse_peek(input) } @@ -353,9 +343,10 @@ where I: Stream, ::Token: AsChar, { - trace("alpha1", move |input: I| { - take_while(1.., |c: ::Token| c.is_alpha()).parse_peek(input) - }) + trace( + "alpha1", + take_while(1.., |c: ::Token| c.is_alpha()), + ) .parse_peek(input) } @@ -397,9 +388,10 @@ where I: Stream, ::Token: AsChar, { - trace("digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_dec_digit()).parse_peek(input) - }) + trace( + "digit0", + take_while(0.., |c: ::Token| c.is_dec_digit()), + ) .parse_peek(input) } @@ -456,9 +448,10 @@ where I: Stream, ::Token: AsChar, { - trace("digit1", move |input: I| { - take_while(1.., |c: ::Token| c.is_dec_digit()).parse_peek(input) - }) + trace( + "digit1", + take_while(1.., |c: ::Token| c.is_dec_digit()), + ) .parse_peek(input) } @@ -498,9 +491,10 @@ where I: Stream, ::Token: AsChar, { - trace("hex_digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_hex_digit()).parse_peek(input) - }) + trace( + "hex_digit0", + take_while(0.., |c: ::Token| c.is_hex_digit()), + ) .parse_peek(input) } @@ -541,9 +535,10 @@ where I: Stream, ::Token: AsChar, { - trace("hex_digit1", move |input: I| { - take_while(1.., |c: ::Token| c.is_hex_digit()).parse_peek(input) - }) + trace( + "hex_digit1", + take_while(1.., |c: ::Token| c.is_hex_digit()), + ) .parse_peek(input) } @@ -584,9 +579,10 @@ where I: Stream, ::Token: AsChar, { - trace("oct_digit0", move |input: I| { - take_while(0.., |c: ::Token| c.is_oct_digit()).parse_peek(input) - }) + trace( + "oct_digit0", + take_while(0.., |c: ::Token| c.is_oct_digit()), + ) .parse_peek(input) } @@ -627,9 +623,10 @@ where I: Stream, ::Token: AsChar, { - trace("oct_digit0", move |input: I| { - take_while(1.., |c: ::Token| c.is_oct_digit()).parse_peek(input) - }) + trace( + "oct_digit0", + take_while(1.., |c: ::Token| c.is_oct_digit()), + ) .parse_peek(input) } @@ -670,9 +667,10 @@ where I: Stream, ::Token: AsChar, { - trace("alphanumeric0", move |input: I| { - take_while(0.., |c: ::Token| c.is_alphanum()).parse_peek(input) - }) + trace( + "alphanumeric0", + take_while(0.., |c: ::Token| c.is_alphanum()), + ) .parse_peek(input) } @@ -713,9 +711,10 @@ where I: Stream, ::Token: AsChar, { - trace("alphanumeric1", move |input: I| { - take_while(1.., |c: ::Token| c.is_alphanum()).parse_peek(input) - }) + trace( + "alphanumeric1", + take_while(1.., |c: ::Token| c.is_alphanum()), + ) .parse_peek(input) } @@ -744,13 +743,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("space0", move |input: I| { + trace( + "space0", take_while(0.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -791,13 +790,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("space1", move |input: I| { + trace( + "space1", take_while(1.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -838,13 +837,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("multispace0", move |input: I| { + trace( + "multispace0", take_while(0.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } @@ -885,13 +884,13 @@ where I: Stream, ::Token: AsChar + Copy, { - trace("multispace1", move |input: I| { + trace( + "multispace1", take_while(1.., |c: ::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') - }) - .parse_peek(input) - }) + }), + ) .parse_peek(input) } diff --git a/src/combinator/parser.rs b/src/combinator/parser.rs index 0038dad5..341eddee 100644 --- a/src/combinator/parser.rs +++ b/src/combinator/parser.rs @@ -1,6 +1,7 @@ use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, ParseError}; use crate::lib::std::borrow::Borrow; use crate::lib::std::ops::Range; +use crate::parser::parser; use crate::stream::StreamIsPartial; use crate::stream::{Location, Stream}; use crate::trace::trace; @@ -20,8 +21,9 @@ impl<'p, P> ByRef<'p, P> { } impl<'p, I, O, E, P: Parser> Parser for ByRef<'p, P> { - fn parse_peek(&mut self, i: I) -> IResult { - self.p.parse_peek(i) + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + self.p.parse_next(i) } } @@ -62,10 +64,11 @@ where F: Parser, G: Fn(O) -> O2, { - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { + #[inline] + fn parse_next(&mut self, i: &mut I) -> PResult { + match self.parser.parse_next(i) { Err(e) => Err(e), - Ok((i, o)) => Ok((i, (self.map)(o))), + Ok(o) => Ok((self.map)(o)), } } } @@ -76,7 +79,7 @@ pub struct TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { parser: F, @@ -92,7 +95,7 @@ impl TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { pub(crate) fn new(parser: F, map: G) -> Self { @@ -112,16 +115,17 @@ impl Parser for TryMap where F: Parser, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - let res = match (self.map)(o) { - Ok(o2) => Ok((input, o2)), - Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::Verify, e)), - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.map)(o).map_err(|err| { + input.reset(start); + ErrMode::from_external_error(input.clone(), ErrorKind::Verify, err) + }); trace_result("verify", &res); res } @@ -133,7 +137,7 @@ pub struct VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { parser: F, @@ -148,7 +152,7 @@ impl VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { pub(crate) fn new(parser: F, map: G) -> Self { @@ -167,16 +171,17 @@ impl Parser for VerifyMap where F: Parser, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - let res = match (self.map)(o) { - Some(o2) => Ok((input, o2)), - None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)), - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.map)(o).ok_or_else(|| { + input.reset(start); + ErrMode::from_error_kind(input.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); res } @@ -189,6 +194,7 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Stream, { outer: F, inner: G, @@ -203,6 +209,7 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Stream, { pub(crate) fn new(outer: F, inner: G) -> Self { Self { @@ -221,12 +228,18 @@ where F: Parser, G: Parser, O: StreamIsPartial, + I: Stream, { - fn parse_peek(&mut self, i: I) -> IResult { - let (i, mut o) = self.outer.parse_peek(i)?; + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + let start = i.checkpoint(); + let mut o = self.outer.parse_next(i)?; let _ = o.complete(); - let (_, o2) = self.inner.parse_peek(o)?; - Ok((i, o2)) + let o2 = self.inner.parse_next(&mut o).map_err(|err| { + i.reset(start); + err + })?; + Ok(o2) } } @@ -271,15 +284,16 @@ where O: crate::stream::ParseSlice, E: ParseError, { - fn parse_peek(&mut self, i: I) -> IResult { - let input = i.clone(); - let (i, o) = self.p.parse_peek(i)?; - - let res = o - .parse_slice() - .ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Verify)); + #[inline] + fn parse_next(&mut self, i: &mut I) -> PResult { + let start = i.checkpoint(); + let o = self.p.parse_next(i)?; + let res = o.parse_slice().ok_or_else(|| { + i.reset(start); + ErrMode::from_error_kind(i.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); - Ok((i, res?)) + res } } @@ -325,9 +339,10 @@ where G: FnMut(O) -> H, H: Parser, { - fn parse_peek(&mut self, i: I) -> IResult { - let (i, o) = self.f.parse_peek(i)?; - (self.g)(o).parse_peek(i) + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + let o = self.f.parse_next(i)?; + (self.g)(o).parse_next(i) } } @@ -349,17 +364,18 @@ where F: Parser, E: ParseError, { - fn parse_peek(&mut self, input: I) -> IResult { - trace("complete_err", |input: I| { - let i = input.clone(); - match (self.f).parse_peek(input) { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + trace( + "complete_err", + parser(|input: &mut I| match (self.f).parse_next(input) { Err(ErrMode::Incomplete(_)) => { - Err(ErrMode::from_error_kind(i, ErrorKind::Complete)) + Err(ErrMode::from_error_kind(input.clone(), ErrorKind::Complete)) } rest => rest, - } - }) - .parse_peek(input) + }), + ) + .parse_next(input) } } @@ -369,7 +385,7 @@ pub struct Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, @@ -386,7 +402,7 @@ impl Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, @@ -407,20 +423,19 @@ impl Parser for Verify where F: Parser, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: Borrow, O2: ?Sized, E: ParseError, { - fn parse_peek(&mut self, input: I) -> IResult { - let i = input.clone(); - let (input, o) = self.parser.parse_peek(input)?; - - let res = if (self.filter)(o.borrow()) { - Ok((input, o)) - } else { - Err(ErrMode::from_error_kind(i, ErrorKind::Verify)) - }; + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + let start = input.checkpoint(); + let o = self.parser.parse_next(input)?; + let res = (self.filter)(o.borrow()).then_some(o).ok_or_else(|| { + input.reset(start); + ErrMode::from_error_kind(input.clone(), ErrorKind::Verify) + }); trace_result("verify", &res); res } @@ -461,10 +476,9 @@ where F: Parser, O2: Clone, { - fn parse_peek(&mut self, input: I) -> IResult { - (self.parser) - .parse_peek(input) - .map(|(i, _)| (i, self.val.clone())) + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult { + (self.parser).parse_next(input).map(|_| self.val.clone()) } } @@ -498,8 +512,9 @@ impl Parser for Void where F: Parser, { - fn parse_peek(&mut self, input: I) -> IResult { - (self.parser).parse_peek(input).map(|(i, _)| (i, ())) + #[inline(always)] + fn parse_next(&mut self, input: &mut I) -> PResult<(), E> { + (self.parser).parse_next(input).map(|_| ()) } } @@ -536,14 +551,15 @@ where F: Parser, I: Stream, { - fn parse_peek(&mut self, input: I) -> IResult::Slice, E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<::Slice, E> { let checkpoint = input.checkpoint(); - match (self.parser).parse_peek(input) { - Ok((mut input, _)) => { + match (self.parser).parse_next(input) { + Ok(_) => { let offset = input.offset_from(&checkpoint); input.reset(checkpoint); - let (input, recognized) = input.peek_slice(offset); - Ok((input, recognized)) + let recognized = input.next_slice(offset); + Ok(recognized) } Err(e) => Err(e), } @@ -583,14 +599,15 @@ where F: Parser, I: Stream, { - fn parse_peek(&mut self, input: I) -> IResult::Slice), E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<(O, ::Slice), E> { let checkpoint = input.checkpoint(); - match (self.parser).parse_peek(input) { - Ok((mut input, result)) => { + match (self.parser).parse_next(input) { + Ok(result) => { let offset = input.offset_from(&checkpoint); input.reset(checkpoint); - let (input, recognized) = input.peek_slice(offset); - Ok((input, (result, recognized))) + let recognized = input.next_slice(offset); + Ok((result, recognized)) } Err(e) => Err(e), } @@ -630,11 +647,12 @@ where F: Parser, I: Clone + Location, { - fn parse_peek(&mut self, input: I) -> IResult, E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult, E> { let start = input.location(); - self.parser.parse_peek(input).map(move |(remaining, _)| { - let end = remaining.location(); - (remaining, (start..end)) + self.parser.parse_next(input).map(move |_| { + let end = input.location(); + start..end }) } } @@ -672,14 +690,13 @@ where F: Parser, I: Clone + Location, { - fn parse_peek(&mut self, input: I) -> IResult), E> { + #[inline] + fn parse_next(&mut self, input: &mut I) -> PResult<(O, Range), E> { let start = input.location(); - self.parser - .parse_peek(input) - .map(move |(remaining, output)| { - let end = remaining.location(); - (remaining, (output, (start..end))) - }) + self.parser.parse_next(input).map(move |output| { + let end = input.location(); + (output, (start..end)) + }) } } @@ -718,11 +735,9 @@ where F: Parser, O: Into, { - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { - Ok((i, o)) => Ok((i, o.into())), - Err(err) => Err(err), - } + #[inline] + fn parse_next(&mut self, i: &mut I) -> PResult { + self.parser.parse_next(i).map(|o| o.into()) } } @@ -761,8 +776,9 @@ where F: Parser, E: Into, { - fn parse_peek(&mut self, i: I) -> IResult { - match self.parser.parse_peek(i) { + #[inline] + fn parse_next(&mut self, i: &mut I) -> PResult { + match self.parser.parse_next(i) { Ok(ok) => Ok(ok), Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())), Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())), @@ -812,16 +828,21 @@ where E: ContextError, C: Clone + crate::lib::std::fmt::Debug, { - fn parse_peek(&mut self, i: I) -> IResult { + #[inline] + fn parse_next(&mut self, i: &mut I) -> PResult { #[cfg(feature = "debug")] let name = format!("context={:?}", self.context); #[cfg(not(feature = "debug"))] let name = "context"; - trace(name, move |i: I| { - (self.parser) - .parse_peek(i.clone()) - .map_err(|err| err.map(|err| err.add_context(i, self.context.clone()))) - }) - .parse_peek(i) + trace( + name, + parser(move |i: &mut I| { + let start = i.clone(); + (self.parser) + .parse_next(i) + .map_err(|err| err.map(|err| err.add_context(start, self.context.clone()))) + }), + ) + .parse_next(i) } } diff --git a/src/parser.rs b/src/parser.rs index 753f6ef9..a515e0ff 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -41,7 +41,7 @@ use crate::stream::{AsChar, Compare, Location, ParseSlice, Stream, StreamIsParti pub trait Parser { /// Parse all of `input`, generating `O` from it #[inline] - fn parse(&mut self, input: I) -> Result + fn parse(&mut self, mut input: I) -> Result where I: Stream, // Force users to deal with `Incomplete` when `StreamIsPartial` @@ -54,11 +54,11 @@ pub trait Parser { "partial streams need to handle `ErrMode::Incomplete`" ); - let (i, o) = self.parse_peek(input).map_err(|e| { + let o = self.parse_next(&mut input).map_err(|e| { e.into_inner() .expect("complete parsers should not report `ErrMode::Incomplete(_)`") })?; - let _ = crate::combinator::eof(i).map_err(|e| { + let _ = crate::combinator::eof.parse_next(&mut input).map_err(|e| { e.into_inner() .expect("complete parsers should not report `ErrMode::Incomplete(_)`") })?; @@ -70,24 +70,18 @@ pub trait Parser { /// This includes advancing the [`Stream`] to the next location. /// /// On error, `input` will be left pointing at the error location. - #[inline(always)] - fn parse_next(&mut self, input: &mut I) -> PResult - where - I: Clone, - { - match self.parse_peek((*input).clone()) { - Ok((i, o)) => { - *input = i; - Ok(o) - } - Err(err) => Err(err), - } - } + fn parse_next(&mut self, input: &mut I) -> PResult; /// Take tokens from the [`Stream`], turning it into the output /// /// This includes advancing the [`Stream`] to the next location. - fn parse_peek(&mut self, input: I) -> IResult; + #[inline(always)] + fn parse_peek(&mut self, mut input: I) -> IResult { + match self.parse_next(&mut input) { + Ok(o) => Ok((input, o)), + Err(err) => Err(err), + } + } /// Treat `&mut Self` as a parser /// @@ -412,7 +406,7 @@ pub trait Parser { where Self: core::marker::Sized, G: FnMut(O) -> Result, - I: Clone, + I: Stream, E: FromExternalError, { TryMap::new(self, map) @@ -446,7 +440,7 @@ pub trait Parser { where Self: core::marker::Sized, G: FnMut(O) -> Option, - I: Clone, + I: Stream, E: ParseError, { VerifyMap::new(self, map) @@ -515,6 +509,7 @@ pub trait Parser { Self: core::marker::Sized, G: Parser, O: StreamIsPartial, + I: Stream, { AndThen::new(self, inner) } @@ -574,7 +569,7 @@ pub trait Parser { where Self: core::marker::Sized, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: crate::lib::std::borrow::Borrow, O2: ?Sized, E: ParseError, @@ -632,7 +627,13 @@ pub trait Parser { impl<'a, I, O, E, F> Parser for F where F: FnMut(I) -> IResult + 'a, + I: Clone, { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + unpeek(|i| self.parse_peek(i))(i) + } + #[inline(always)] fn parse_peek(&mut self, i: I) -> IResult { self(i) @@ -661,8 +662,8 @@ where E: ParseError, { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { - crate::token::one_of(*self).parse_peek(i) + fn parse_next(&mut self, i: &mut I) -> PResult { + crate::token::one_of(*self).parse_next(i) } } @@ -689,8 +690,8 @@ where E: ParseError, { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Token, E> { - crate::token::one_of(*self).parse_peek(i) + fn parse_next(&mut self, i: &mut I) -> PResult<::Token, E> { + crate::token::one_of(*self).parse_next(i) } } @@ -718,8 +719,8 @@ where I: Stream, { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + crate::token::tag(*self).parse_next(i) } } @@ -747,8 +748,8 @@ where I: Stream, { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + crate::token::tag(*self).parse_next(i) } } @@ -776,15 +777,15 @@ where I: Stream, { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult::Slice, E> { - crate::token::tag(*self).parse_peek(i) + fn parse_next(&mut self, i: &mut I) -> PResult<::Slice, E> { + crate::token::tag(*self).parse_next(i) } } impl> Parser for () { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { - Ok((i, ())) + fn parse_next(&mut self, _i: &mut I) -> PResult<(), E> { + Ok(()) } } @@ -796,12 +797,12 @@ macro_rules! impl_parser_for_tuple { $($parser: Parser),+ { #[inline(always)] - fn parse_peek(&mut self, i: I) -> IResult { + fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> { let ($(ref mut $parser),+,) = *self; - $(let(i, $output) = $parser.parse_peek(i)?;)+ + $(let $output = $parser.parse_next(i)?;)+ - Ok((i, ($($output),+,))) + Ok(($($output),+,)) } } ) @@ -850,9 +851,63 @@ use alloc::boxed::Box; #[cfg(feature = "alloc")] impl<'a, I, O, E> Parser for Box + 'a> { #[inline(always)] - fn parse_peek(&mut self, input: I) -> IResult { - (**self).parse_peek(input) + fn parse_next(&mut self, i: &mut I) -> PResult { + (**self).parse_next(i) + } +} + +#[inline(always)] +pub(crate) fn unpeek<'a, I, O, E>( + mut peek: impl FnMut(I) -> IResult + 'a, +) -> impl FnMut(&mut I) -> PResult +where + I: Clone, +{ + move |input| match peek((*input).clone()) { + Ok((i, o)) => { + *input = i; + Ok(o) + } + Err(err) => Err(err), + } +} + +#[inline(always)] +pub(crate) fn parser(parser: impl FnMut(&mut I) -> PResult) -> impl Parser { + struct Wrapper + where + P: FnMut(&mut I) -> PResult, + { + p: P, + i: core::marker::PhantomData, + o: core::marker::PhantomData, + e: core::marker::PhantomData, + } + + impl Wrapper + where + P: FnMut(&mut I) -> PResult, + { + pub(crate) fn new(p: P) -> Self { + Self { + p, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } + } + + impl Parser for Wrapper + where + P: FnMut(&mut I) -> PResult, + { + #[inline(always)] + fn parse_next(&mut self, i: &mut I) -> PResult { + (self.p)(i) + } } + Wrapper::new(parser) } #[cfg(test)]