summaryrefslogtreecommitdiffstats
path: root/vendor/winnow/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/winnow/src/parser.rs')
-rw-r--r--vendor/winnow/src/parser.rs394
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(("", ())));
}
}