diff options
Diffstat (limited to 'vendor/winnow/src/parser.rs')
-rw-r--r-- | vendor/winnow/src/parser.rs | 394 |
1 files changed, 211 insertions, 183 deletions
diff --git a/vendor/winnow/src/parser.rs b/vendor/winnow/src/parser.rs index 15d892864..d160a8ef8 100644 --- a/vendor/winnow/src/parser.rs +++ b/vendor/winnow/src/parser.rs @@ -1,8 +1,8 @@ //! Basic types to build the parsers use crate::combinator::*; -use crate::error::{ContextError, FromExternalError, IResult, ParseError}; -use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, StreamIsPartial}; +use crate::error::{AddContext, FromExternalError, IResult, PResult, ParseError, ParserError}; +use crate::stream::{AsChar, Compare, Location, ParseSlice, Stream, StreamIsPartial}; /// Core trait for parsing /// @@ -10,12 +10,12 @@ use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, Strea /// ```rust /// use winnow::prelude::*; /// -/// fn success(input: &str) -> IResult<&str, ()> { +/// fn success(input: &mut &str) -> PResult<()> { /// let output = (); -/// Ok((input, output)) +/// Ok(output) /// } /// -/// let (input, output) = success.parse_next("Hello").unwrap(); +/// let (input, output) = success.parse_peek("Hello").unwrap(); /// assert_eq!(input, "Hello"); // We didn't consume any input /// ``` /// @@ -23,14 +23,14 @@ use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, Strea /// ```rust /// use winnow::prelude::*; /// -/// fn success<O: Clone>(output: O) -> impl FnMut(&str) -> IResult<&str, O> { -/// move |input: &str| { +/// fn success<O: Clone>(output: O) -> impl FnMut(&mut &str) -> PResult<O> { +/// move |input: &mut &str| { /// let output = output.clone(); -/// Ok((input, output)) +/// Ok(output) /// } /// } /// -/// let (input, output) = success("World").parse_next("Hello").unwrap(); +/// let (input, output) = success("World").parse_peek("Hello").unwrap(); /// assert_eq!(input, "Hello"); // We didn't consume any input /// assert_eq!(output, "World"); /// ``` @@ -41,23 +41,49 @@ use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, Strea pub trait Parser<I, O, E> { /// Parse all of `input`, generating `O` from it #[inline] - fn parse(&mut self, input: I) -> Result<O, E> + fn parse(&mut self, mut input: I) -> Result<O, ParseError<I, E>> where + Self: core::marker::Sized, I: Stream, // Force users to deal with `Incomplete` when `StreamIsPartial<true>` I: StreamIsPartial, I: Clone, - E: ParseError<I>, + E: ParserError<I>, { - #![allow(deprecated)] - use crate::error::FinishIResult; - self.parse_next(input).finish() + debug_assert!( + !I::is_partial_supported(), + "partial streams need to handle `ErrMode::Incomplete`" + ); + + let start = input.checkpoint(); + let (o, _) = (self.by_ref(), crate::combinator::eof) + .parse_next(&mut input) + .map_err(|e| { + let e = e + .into_inner() + .expect("complete parsers should not report `ErrMode::Incomplete(_)`"); + ParseError::new(input, start, e) + })?; + Ok(o) } /// Take tokens from the [`Stream`], turning it into the output /// /// This includes advancing the [`Stream`] to the next location. - fn parse_next(&mut self, input: I) -> IResult<I, O, E>; + /// + /// On error, `input` will be left pointing at the error location. + fn parse_next(&mut self, input: &mut I) -> PResult<O, E>; + + /// Take tokens from the [`Stream`], turning it into the output + /// + /// This includes advancing the [`Stream`] to the next location. + #[inline(always)] + fn parse_peek(&mut self, mut input: I) -> IResult<I, O, E> { + match self.parse_next(&mut input) { + Ok(o) => Ok((input, o)), + Err(err) => Err(err), + } + } /// Treat `&mut Self` as a parser /// @@ -70,18 +96,17 @@ pub trait Parser<I, O, E> { /// [`Parser::complete_err`]: /// ```rust,compile_fail /// # use winnow::prelude::*; - /// # use winnow::IResult; /// # use winnow::Parser; - /// # use winnow::error::ParseError; + /// # use winnow::error::ParserError; /// # use winnow::binary::length_data; - /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( + /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>( /// mut f: impl Parser<&'i [u8], usize, E>, /// mut g: impl Parser<&'i [u8], O, E> - /// ) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], O, E> { - /// move |i: &'i [u8]| { - /// let (i, data) = length_data(f).parse_next(i)?; - /// let (_, o) = g.complete().parse_next(data)?; - /// Ok((i, o)) + /// ) -> impl Parser<&'i [u8], O, E> { + /// move |i: &mut &'i [u8]| { + /// let mut data = length_data(f).parse_next(i)?; + /// let o = g.complete_err().parse_next(&mut data)?; + /// Ok(o) /// } /// } /// ``` @@ -89,18 +114,17 @@ pub trait Parser<I, O, E> { /// By adding `by_ref`, we can make this work: /// ```rust /// # use winnow::prelude::*; - /// # use winnow::IResult; /// # use winnow::Parser; - /// # use winnow::error::ParseError; + /// # use winnow::error::ParserError; /// # use winnow::binary::length_data; - /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( + /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>( /// mut f: impl Parser<&'i [u8], usize, E>, /// mut g: impl Parser<&'i [u8], O, E> - /// ) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], O, E> { - /// move |i: &'i [u8]| { - /// let (i, data) = length_data(f.by_ref()).parse_next(i)?; - /// let (_, o) = g.by_ref().complete_err().parse_next(data)?; - /// Ok((i, o)) + /// ) -> impl Parser<&'i [u8], O, E> { + /// move |i: &mut &'i [u8]| { + /// let mut data = length_data(f.by_ref()).parse_next(i)?; + /// let o = g.by_ref().complete_err().parse_next(&mut data)?; + /// Ok(o) /// } /// } /// ``` @@ -116,14 +140,14 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.value(1234); /// - /// assert_eq!(parser.parse_next("abcd"), Ok(("", 1234))); - /// assert_eq!(parser.parse_next("123abcd;"), Err(ErrMode::Backtrack(Error::new("123abcd;", ErrorKind::Slice)))); + /// assert_eq!(parser.parse_peek("abcd"), Ok(("", 1234))); + /// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice)))); /// # } /// ``` #[doc(alias = "to")] @@ -140,14 +164,14 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.void(); /// - /// assert_eq!(parser.parse_next("abcd"), Ok(("", ()))); - /// assert_eq!(parser.parse_next("123abcd;"), Err(ErrMode::Backtrack(Error::new("123abcd;", ErrorKind::Slice)))); + /// assert_eq!(parser.parse_peek("abcd"), Ok(("", ()))); + /// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice)))); /// # } /// ``` fn void(self) -> Void<Self, I, O, E> @@ -162,19 +186,19 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::IResult; - /// # use winnow::Parser; + /// # use winnow::prelude::*; + /// # use winnow::error::InputError; /// use winnow::ascii::alpha1; /// # fn main() { /// - /// fn parser1(i: &str) -> IResult<&str, &str> { + /// fn parser1<'s>(i: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> { /// alpha1(i) /// } /// /// let mut parser2 = parser1.output_into(); /// /// // the parser converts the &str output of the child parser into a Vec<u8> - /// let bytes: IResult<&str, Vec<u8>> = parser2.parse_next("abcd"); + /// let bytes: IResult<&str, Vec<u8>> = parser2.parse_peek("abcd"); /// assert_eq!(bytes, Ok(("", vec![97, 98, 99, 100]))); /// # } /// ``` @@ -191,22 +215,22 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::{alpha1}; /// use winnow::combinator::separated_pair; /// # fn main() { /// /// let mut parser = separated_pair(alpha1, ',', alpha1).recognize(); /// - /// assert_eq!(parser.parse_next("abcd,efgh"), Ok(("", "abcd,efgh"))); - /// assert_eq!(parser.parse_next("abcd;"),Err(ErrMode::Backtrack(Error::new(";", ErrorKind::Verify)))); + /// assert_eq!(parser.parse_peek("abcd,efgh"), Ok(("", "abcd,efgh"))); + /// assert_eq!(parser.parse_peek("abcd;"),Err(ErrMode::Backtrack(InputError::new(";", ErrorKind::Verify)))); /// # } /// ``` #[doc(alias = "concat")] fn recognize(self) -> Recognize<Self, I, O, E> where Self: core::marker::Sized, - I: Stream + Offset, + I: Stream, { Recognize::new(self) } @@ -225,36 +249,33 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::prelude::*; - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError}; /// use winnow::ascii::{alpha1}; /// use winnow::token::tag; /// use winnow::combinator::separated_pair; /// - /// fn inner_parser(input: &str) -> IResult<&str, bool> { + /// fn inner_parser<'s>(input: &mut &'s str) -> PResult<bool, InputError<&'s str>> { /// "1234".value(true).parse_next(input) /// } /// - /// # fn main() { - /// /// let mut consumed_parser = separated_pair(alpha1, ',', alpha1).value(true).with_recognized(); /// - /// assert_eq!(consumed_parser.parse_next("abcd,efgh1"), Ok(("1", (true, "abcd,efgh")))); - /// assert_eq!(consumed_parser.parse_next("abcd;"),Err(ErrMode::Backtrack(Error::new(";", ErrorKind::Verify)))); + /// assert_eq!(consumed_parser.parse_peek("abcd,efgh1"), Ok(("1", (true, "abcd,efgh")))); + /// assert_eq!(consumed_parser.parse_peek("abcd;"),Err(ErrMode::Backtrack(InputError::new(";", ErrorKind::Verify)))); /// /// // the second output (representing the consumed input) /// // should be the same as that of the `recognize` parser. /// let mut recognize_parser = inner_parser.recognize(); /// let mut consumed_parser = inner_parser.with_recognized().map(|(output, consumed)| consumed); /// - /// assert_eq!(recognize_parser.parse_next("1234"), consumed_parser.parse_next("1234")); - /// assert_eq!(recognize_parser.parse_next("abcd"), consumed_parser.parse_next("abcd")); - /// # } + /// assert_eq!(recognize_parser.parse_peek("1234"), consumed_parser.parse_peek("1234")); + /// assert_eq!(recognize_parser.parse_peek("abcd"), consumed_parser.parse_peek("abcd")); /// ``` #[doc(alias = "consumed")] fn with_recognized(self) -> WithRecognized<Self, I, O, E> where Self: core::marker::Sized, - I: Stream + Offset, + I: Stream, { WithRecognized::new(self) } @@ -265,7 +286,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::prelude::*; - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, stream::Stream}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, stream::Stream}; /// use winnow::stream::Located; /// use winnow::ascii::alpha1; /// use winnow::combinator::separated_pair; @@ -273,7 +294,7 @@ pub trait Parser<I, O, E> { /// let mut parser = separated_pair(alpha1.span(), ',', alpha1.span()); /// /// assert_eq!(parser.parse(Located::new("abcd,efgh")), Ok((0..4, 5..9))); - /// assert_eq!(parser.parse_next(Located::new("abcd;")),Err(ErrMode::Backtrack(Error::new(Located::new("abcd;").next_slice(4).0, ErrorKind::Verify)))); + /// assert_eq!(parser.parse_peek(Located::new("abcd;")),Err(ErrMode::Backtrack(InputError::new(Located::new("abcd;").peek_slice(4).0, ErrorKind::Verify)))); /// ``` fn span(self) -> Span<Self, I, O, E> where @@ -297,13 +318,13 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::prelude::*; - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, stream::Stream}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, stream::Stream}; /// use winnow::stream::Located; /// use winnow::ascii::alpha1; /// use winnow::token::tag; /// use winnow::combinator::separated_pair; /// - /// fn inner_parser(input: Located<&str>) -> IResult<Located<&str>, bool> { + /// fn inner_parser<'s>(input: &mut Located<&'s str>) -> PResult<bool, InputError<Located<&'s str>>> { /// "1234".value(true).parse_next(input) /// } /// @@ -312,15 +333,15 @@ pub trait Parser<I, O, E> { /// let mut consumed_parser = separated_pair(alpha1.value(1).with_span(), ',', alpha1.value(2).with_span()); /// /// assert_eq!(consumed_parser.parse(Located::new("abcd,efgh")), Ok(((1, 0..4), (2, 5..9)))); - /// assert_eq!(consumed_parser.parse_next(Located::new("abcd;")),Err(ErrMode::Backtrack(Error::new(Located::new("abcd;").next_slice(4).0, ErrorKind::Verify)))); + /// assert_eq!(consumed_parser.parse_peek(Located::new("abcd;")),Err(ErrMode::Backtrack(InputError::new(Located::new("abcd;").peek_slice(4).0, ErrorKind::Verify)))); /// /// // the second output (representing the consumed input) /// // should be the same as that of the `span` parser. /// let mut recognize_parser = inner_parser.span(); /// let mut consumed_parser = inner_parser.with_span().map(|(output, consumed)| consumed); /// - /// assert_eq!(recognize_parser.parse_next(Located::new("1234")), consumed_parser.parse_next(Located::new("1234"))); - /// assert_eq!(recognize_parser.parse_next(Located::new("abcd")), consumed_parser.parse_next(Located::new("abcd"))); + /// assert_eq!(recognize_parser.parse_peek(Located::new("1234")), consumed_parser.parse_peek(Located::new("1234"))); + /// assert_eq!(recognize_parser.parse_peek(Located::new("abcd")), consumed_parser.parse_peek(Located::new("abcd"))); /// # } /// ``` fn with_span(self) -> WithSpan<Self, I, O, E> @@ -336,17 +357,17 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; + /// use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::digit1; /// # fn main() { /// /// let mut parser = digit1.map(|s: &str| s.len()); /// /// // the parser will count how many characters were returned by digit1 - /// assert_eq!(parser.parse_next("123456"), Ok(("", 6))); + /// assert_eq!(parser.parse_peek("123456"), Ok(("", 6))); /// /// // this will fail if digit1 fails - /// assert_eq!(parser.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Slice)))); + /// assert_eq!(parser.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice)))); /// # } /// ``` fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E> @@ -362,63 +383,51 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::digit1; /// # fn main() { /// /// let mut parse = digit1.try_map(|s: &str| s.parse::<u8>()); /// /// // the parser will convert the result of digit1 to a number - /// assert_eq!(parse.parse_next("123"), Ok(("", 123))); + /// assert_eq!(parse.parse_peek("123"), Ok(("", 123))); /// /// // this will fail if digit1 fails - /// assert_eq!(parse.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Slice)))); + /// assert_eq!(parse.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice)))); /// /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`) - /// assert_eq!(parse.parse_next("123456"), Err(ErrMode::Backtrack(Error::new("123456", ErrorKind::Verify)))); + /// assert_eq!(parse.parse_peek("123456"), Err(ErrMode::Backtrack(InputError::new("123456", ErrorKind::Verify)))); /// # } /// ``` fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2> where Self: core::marker::Sized, G: FnMut(O) -> Result<O2, E2>, - I: Clone, + I: Stream, E: FromExternalError<I, E2>, { TryMap::new(self, map) } - /// Deprecated, see [`Parser::try_map`] - #[deprecated(since = "0.4.2", note = "Replaced with `Parser::try_map`")] - fn map_res<G, O2, E2>(self, map: G) -> MapRes<Self, G, I, O, O2, E, E2> - where - Self: core::marker::Sized, - G: FnMut(O) -> Result<O2, E2>, - I: Clone, - E: FromExternalError<I, E2>, - { - self.try_map(map) - } - /// Apply both [`Parser::verify`] and [`Parser::map`]. /// /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::digit1; /// # fn main() { /// /// let mut parse = digit1.verify_map(|s: &str| s.parse::<u8>().ok()); /// /// // the parser will convert the result of digit1 to a number - /// assert_eq!(parse.parse_next("123"), Ok(("", 123))); + /// assert_eq!(parse.parse_peek("123"), Ok(("", 123))); /// /// // this will fail if digit1 fails - /// assert_eq!(parse.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Slice)))); + /// assert_eq!(parse.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice)))); /// /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`) - /// assert_eq!(parse.parse_next("123456"), Err(ErrMode::Backtrack(Error::new("123456", ErrorKind::Verify)))); + /// assert_eq!(parse.parse_peek("123456"), Err(ErrMode::Backtrack(InputError::new("123456", ErrorKind::Verify)))); /// # } /// ``` #[doc(alias = "satisfy_map")] @@ -428,8 +437,8 @@ pub trait Parser<I, O, E> { where Self: core::marker::Sized, G: FnMut(O) -> Option<O2>, - I: Clone, - E: ParseError<I>, + I: Stream, + E: ParserError<I>, { VerifyMap::new(self, map) } @@ -439,32 +448,32 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, PResult, Parser}; /// use winnow::token::take; /// use winnow::binary::u8; /// - /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { + /// fn length_data<'s>(input: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> { /// u8.flat_map(take).parse_next(input) /// } /// - /// assert_eq!(length_data.parse_next(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); - /// assert_eq!(length_data.parse_next(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(Error::new(&[0, 1, 2][..], ErrorKind::Slice)))); + /// assert_eq!(length_data.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); + /// assert_eq!(length_data.parse_peek(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(InputError::new(&[0, 1, 2][..], ErrorKind::Slice)))); /// ``` /// /// which is the same as /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, PResult, Parser}; /// use winnow::token::take; /// use winnow::binary::u8; /// - /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { - /// let (input, length) = u8.parse_next(input)?; - /// let (input, data) = take(length).parse_next(input)?; - /// Ok((input, data)) + /// fn length_data<'s>(input: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> { + /// let length = u8.parse_next(input)?; + /// let data = take(length).parse_next(input)?; + /// Ok(data) /// } /// - /// assert_eq!(length_data.parse_next(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); - /// assert_eq!(length_data.parse_next(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(Error::new(&[0, 1, 2][..], ErrorKind::Slice)))); + /// assert_eq!(length_data.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); + /// assert_eq!(length_data.parse_peek(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(InputError::new(&[0, 1, 2][..], ErrorKind::Slice)))); /// ``` fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E> where @@ -480,16 +489,16 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::digit1; /// use winnow::token::take; /// # fn main() { /// /// let mut digits = take(5u8).and_then(digit1); /// - /// assert_eq!(digits.parse_next("12345"), Ok(("", "12345"))); - /// assert_eq!(digits.parse_next("123ab"), Ok(("", "123"))); - /// assert_eq!(digits.parse_next("123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Slice)))); + /// assert_eq!(digits.parse_peek("12345"), Ok(("", "12345"))); + /// assert_eq!(digits.parse_peek("123ab"), Ok(("", "123"))); + /// assert_eq!(digits.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Slice)))); /// # } /// ``` fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E> @@ -497,6 +506,7 @@ pub trait Parser<I, O, E> { Self: core::marker::Sized, G: Parser<O, O2, E>, O: StreamIsPartial, + I: Stream, { AndThen::new(self, inner) } @@ -507,18 +517,18 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::prelude::*; - /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; + /// use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// use winnow::ascii::digit1; /// - /// fn parser(input: &str) -> IResult<&str, u64> { + /// fn parser<'s>(input: &mut &'s str) -> PResult<u64, InputError<&'s str>> { /// digit1.parse_to().parse_next(input) /// } /// /// // the parser will count how many characters were returned by digit1 - /// assert_eq!(parser.parse_next("123456"), Ok(("", 123456))); + /// assert_eq!(parser.parse_peek("123456"), Ok(("", 123456))); /// /// // this will fail if digit1 fails - /// assert_eq!(parser.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Slice)))); + /// assert_eq!(parser.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice)))); /// ``` #[doc(alias = "from_str")] fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E> @@ -526,7 +536,7 @@ pub trait Parser<I, O, E> { Self: core::marker::Sized, I: Stream, O: ParseSlice<O2>, - E: ParseError<I>, + E: ParserError<I>, { ParseTo::new(self) } @@ -539,15 +549,15 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; + /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser}; /// # use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.verify(|s: &str| s.len() == 4); /// - /// assert_eq!(parser.parse_next("abcd"), Ok(("", "abcd"))); - /// assert_eq!(parser.parse_next("abcde"), Err(ErrMode::Backtrack(Error::new("abcde", ErrorKind::Verify)))); - /// assert_eq!(parser.parse_next("123abcd;"),Err(ErrMode::Backtrack(Error::new("123abcd;", ErrorKind::Slice)))); + /// assert_eq!(parser.parse_peek("abcd"), Ok(("", "abcd"))); + /// assert_eq!(parser.parse_peek("abcde"), Err(ErrMode::Backtrack(InputError::new("abcde", ErrorKind::Verify)))); + /// assert_eq!(parser.parse_peek("123abcd;"),Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice)))); /// # } /// ``` #[doc(alias = "satisfy")] @@ -556,10 +566,10 @@ pub trait Parser<I, O, E> { where Self: core::marker::Sized, G: Fn(&O2) -> bool, - I: Clone, + I: Stream, O: crate::lib::std::borrow::Borrow<O2>, O2: ?Sized, - E: ParseError<I>, + E: ParserError<I>, { Verify::new(self, filter) } @@ -573,7 +583,7 @@ pub trait Parser<I, O, E> { where Self: core::marker::Sized, I: Stream, - E: ContextError<I, C>, + E: AddContext<I, C>, C: Clone + crate::lib::std::fmt::Debug, { Context::new(self, context) @@ -584,14 +594,14 @@ pub trait Parser<I, O, E> { /// # Example /// /// ```rust - /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, stream::Partial, Parser}; + /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, stream::Partial, Parser}; /// # use winnow::token::take; /// # fn main() { /// /// let mut parser = take(5u8).complete_err(); /// - /// assert_eq!(parser.parse_next(Partial::new("abcdefg")), Ok((Partial::new("fg"), "abcde"))); - /// assert_eq!(parser.parse_next(Partial::new("abcd")), Err(ErrMode::Backtrack(Error::new(Partial::new("abcd"), ErrorKind::Complete)))); + /// assert_eq!(parser.parse_peek(Partial::new("abcdefg")), Ok((Partial::new("fg"), "abcde"))); + /// assert_eq!(parser.parse_peek(Partial::new("abcd")), Err(ErrMode::Backtrack(InputError::new(Partial::new("abcd"), ErrorKind::Complete)))); /// # } /// ``` fn complete_err(self) -> CompleteErr<Self> @@ -613,10 +623,11 @@ pub trait Parser<I, O, E> { impl<'a, I, O, E, F> Parser<I, O, E> for F where - F: FnMut(I) -> IResult<I, O, E> + 'a, + F: FnMut(&mut I) -> PResult<O, E> + 'a, + I: Stream, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, O, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<O, E> { self(i) } } @@ -627,23 +638,23 @@ where /// /// ``` /// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{ErrorKind, Error}}; -/// fn parser(i: &[u8]) -> IResult<&[u8], u8> { +/// # use winnow::{error::ErrMode, error::{ErrorKind, InputError}}; +/// fn parser<'s>(i: &mut &'s [u8]) -> PResult<u8, InputError<&'s [u8]>> { /// b'a'.parse_next(i) /// } -/// assert_eq!(parser(&b"abc"[..]), Ok((&b"bc"[..], b'a'))); -/// assert_eq!(parser(&b" abc"[..]), Err(ErrMode::Backtrack(Error::new(&b" abc"[..], ErrorKind::Verify)))); -/// assert_eq!(parser(&b"bc"[..]), Err(ErrMode::Backtrack(Error::new(&b"bc"[..], ErrorKind::Verify)))); -/// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(Error::new(&b""[..], ErrorKind::Token)))); +/// assert_eq!(parser.parse_peek(&b"abc"[..]), Ok((&b"bc"[..], b'a'))); +/// assert_eq!(parser.parse_peek(&b" abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b" abc"[..], ErrorKind::Verify)))); +/// assert_eq!(parser.parse_peek(&b"bc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"bc"[..], ErrorKind::Verify)))); +/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Token)))); /// ``` impl<I, E> Parser<I, u8, E> for u8 where I: StreamIsPartial, I: Stream<Token = u8>, - E: ParseError<I>, + E: ParserError<I>, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, u8, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<u8, E> { crate::token::one_of(*self).parse_next(i) } } @@ -654,24 +665,24 @@ where /// /// ``` /// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{ErrorKind, Error}}; -/// fn parser(i: &str) -> IResult<&str, char> { +/// # use winnow::{error::ErrMode, error::{ErrorKind, InputError}}; +/// fn parser<'s>(i: &mut &'s str) -> PResult<char, InputError<&'s str>> { /// 'a'.parse_next(i) /// } -/// assert_eq!(parser("abc"), Ok(("bc", 'a'))); -/// assert_eq!(parser(" abc"), Err(ErrMode::Backtrack(Error::new(" abc", ErrorKind::Verify)))); -/// assert_eq!(parser("bc"), Err(ErrMode::Backtrack(Error::new("bc", ErrorKind::Verify)))); -/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Token)))); +/// assert_eq!(parser.parse_peek("abc"), Ok(("bc", 'a'))); +/// assert_eq!(parser.parse_peek(" abc"), Err(ErrMode::Backtrack(InputError::new(" abc", ErrorKind::Verify)))); +/// assert_eq!(parser.parse_peek("bc"), Err(ErrMode::Backtrack(InputError::new("bc", ErrorKind::Verify)))); +/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Token)))); /// ``` impl<I, E> Parser<I, <I as Stream>::Token, E> for char where I: StreamIsPartial, I: Stream, - <I as Stream>::Token: AsChar + Copy, - E: ParseError<I>, + <I as Stream>::Token: AsChar + Clone, + E: ParserError<I>, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Token, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Token, E> { crate::token::one_of(*self).parse_next(i) } } @@ -681,26 +692,26 @@ where /// # Example /// ```rust /// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed}; /// # use winnow::combinator::alt; /// # use winnow::token::take; /// -/// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { +/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> { /// alt((&"Hello"[..], take(5usize))).parse_next(s) /// } /// -/// assert_eq!(parser(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..]))); -/// assert_eq!(parser(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..]))); -/// assert_eq!(parser(&b"Some"[..]), Err(ErrMode::Backtrack(Error::new(&b"Some"[..], ErrorKind::Slice)))); -/// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(Error::new(&b""[..], ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..]))); +/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..]))); +/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice)))); /// ``` -impl<'s, I, E: ParseError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8] +impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8] where I: Compare<&'s [u8]> + StreamIsPartial, I: Stream, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> { crate::token::tag(*self).parse_next(i) } } @@ -710,26 +721,26 @@ where /// # Example /// ```rust /// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed}; /// # use winnow::combinator::alt; /// # use winnow::token::take; /// -/// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { +/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> { /// alt((b"Hello", take(5usize))).parse_next(s) /// } /// -/// assert_eq!(parser(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..]))); -/// assert_eq!(parser(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..]))); -/// assert_eq!(parser(&b"Some"[..]), Err(ErrMode::Backtrack(Error::new(&b"Some"[..], ErrorKind::Slice)))); -/// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(Error::new(&b""[..], ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..]))); +/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..]))); +/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice)))); /// ``` -impl<'s, I, E: ParseError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N] +impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N] where I: Compare<&'s [u8; N]> + StreamIsPartial, I: Stream, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> { crate::token::tag(*self).parse_next(i) } } @@ -739,51 +750,51 @@ where /// # Example /// ```rust /// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}}; +/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}}; /// # use winnow::combinator::alt; /// # use winnow::token::take; /// -/// fn parser(s: &str) -> IResult<&str, &str> { +/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> { /// alt(("Hello", take(5usize))).parse_next(s) /// } /// -/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello"))); -/// assert_eq!(parser("Something"), Ok(("hing", "Somet"))); -/// assert_eq!(parser("Some"), Err(ErrMode::Backtrack(Error::new("Some", ErrorKind::Slice)))); -/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello"))); +/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet"))); +/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Slice)))); +/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice)))); /// ``` -impl<'s, I, E: ParseError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str +impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str where I: Compare<&'s str> + StreamIsPartial, I: Stream, { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { + fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> { crate::token::tag(*self).parse_next(i) } } -impl<I, E: ParseError<I>> Parser<I, (), E> for () { +impl<I, E: ParserError<I>> Parser<I, (), E> for () { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, (), E> { - Ok((i, ())) + fn parse_next(&mut self, _i: &mut I) -> PResult<(), E> { + Ok(()) } } macro_rules! impl_parser_for_tuple { ($($parser:ident $output:ident),+) => ( #[allow(non_snake_case)] - impl<I, $($output),+, E: ParseError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,) + impl<I, $($output),+, E: ParserError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,) where $($parser: Parser<I, $output, E>),+ { #[inline(always)] - fn parse_next(&mut self, i: I) -> IResult<I, ($($output),+,), E> { + fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> { let ($(ref mut $parser),+,) = *self; - $(let(i, $output) = $parser.parse_next(i)?;)+ + $(let $output = $parser.parse_next(i)?;)+ - Ok((i, ($($output),+,))) + Ok(($($output),+,)) } } ) @@ -832,8 +843,25 @@ use alloc::boxed::Box; #[cfg(feature = "alloc")] impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> { #[inline(always)] - fn parse_next(&mut self, input: I) -> IResult<I, O, E> { - (**self).parse_next(input) + fn parse_next(&mut self, i: &mut I) -> PResult<O, E> { + (**self).parse_next(i) + } +} + +/// Convert a [`Parser::parse_peek`] style parse function to be a [`Parser`] +#[inline(always)] +pub fn unpeek<'a, I, O, E>( + mut peek: impl FnMut(I) -> IResult<I, O, E> + 'a, +) -> impl FnMut(&mut I) -> PResult<O, E> +where + I: Clone, +{ + move |input| match peek((*input).clone()) { + Ok((i, o)) => { + *input = i; + Ok(o) + } + Err(err) => Err(err), } } @@ -842,8 +870,8 @@ mod tests { use super::*; use crate::binary::be_u16; use crate::error::ErrMode; - use crate::error::Error; use crate::error::ErrorKind; + use crate::error::InputError; use crate::error::Needed; use crate::token::take; use crate::Partial; @@ -878,13 +906,13 @@ mod tests { use crate::error::ErrorKind; let mut parser = (alpha1,); - assert_eq!(parser.parse_next("abc123def"), Ok(("123def", ("abc",)))); + assert_eq!(parser.parse_peek("abc123def"), Ok(("123def", ("abc",)))); assert_eq!( - parser.parse_next("123def"), - Err(ErrMode::Backtrack(Error { - input: "123def", - kind: ErrorKind::Slice - })) + parser.parse_peek("123def"), + Err(ErrMode::Backtrack(InputError::new( + "123def", + ErrorKind::Slice + ))) ); } @@ -892,7 +920,7 @@ mod tests { fn tuple_test() { #[allow(clippy::type_complexity)] fn tuple_3(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u16, &[u8], &[u8])> { - (be_u16, take(3u8), "fg").parse_next(i) + (be_u16, take(3u8), "fg").parse_peek(i) } assert_eq!( @@ -913,7 +941,7 @@ mod tests { assert_eq!( tuple_3(Partial::new(&b"abcdejk"[..])), Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"jk"[..]), + &Partial::new(&b"jk"[..]), ErrorKind::Tag ))) ); @@ -921,11 +949,11 @@ mod tests { #[test] fn unit_type() { - fn parser(i: &str) -> IResult<&str, ()> { + fn parser(i: &mut &str) -> PResult<()> { ().parse_next(i) } - assert_eq!(parser.parse_next("abxsbsh"), Ok(("abxsbsh", ()))); - assert_eq!(parser.parse_next("sdfjakdsas"), Ok(("sdfjakdsas", ()))); - assert_eq!(parser.parse_next(""), Ok(("", ()))); + assert_eq!(parser.parse_peek("abxsbsh"), Ok(("abxsbsh", ()))); + assert_eq!(parser.parse_peek("sdfjakdsas"), Ok(("sdfjakdsas", ()))); + assert_eq!(parser.parse_peek(""), Ok(("", ()))); } } |