summaryrefslogtreecommitdiffstats
path: root/vendor/winnow/src/_tutorial
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:35 +0000
commitd1b2d29528b7794b41e66fc2136e395a02f8529b (patch)
treea4a17504b260206dec3cf55b2dca82929a348ac2 /vendor/winnow/src/_tutorial
parentReleasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz
rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/winnow/src/_tutorial')
-rw-r--r--vendor/winnow/src/_tutorial/chapter_1.rs44
-rw-r--r--vendor/winnow/src/_tutorial/chapter_2.rs185
-rw-r--r--vendor/winnow/src/_tutorial/chapter_3.rs249
-rw-r--r--vendor/winnow/src/_tutorial/chapter_4.rs48
-rw-r--r--vendor/winnow/src/_tutorial/chapter_5.rs185
-rw-r--r--vendor/winnow/src/_tutorial/chapter_6.rs89
-rw-r--r--vendor/winnow/src/_tutorial/chapter_7.rs72
7 files changed, 581 insertions, 291 deletions
diff --git a/vendor/winnow/src/_tutorial/chapter_1.rs b/vendor/winnow/src/_tutorial/chapter_1.rs
index d6a45c8b7..1bf146bec 100644
--- a/vendor/winnow/src/_tutorial/chapter_1.rs
+++ b/vendor/winnow/src/_tutorial/chapter_1.rs
@@ -9,51 +9,47 @@
//! - `Ok` indicates the parser successfully found what it was looking for; or
//! - `Err` indicates the parser could not find what it was looking for.
//!
-//! Parsers do more than just return a binary "success"/"failure" code. If
-//! the parser was successful, then it will return a tuple where the first field
-//! will contain everything the parser did not process. The second will contain
-//! everything the parser processed. The idea is that a parser can happily parse the first
-//! *part* of an input, without being able to parse the whole thing.
+//! Parsers do more than just return a binary "success"/"failure" code.
+//! On success, the parser will return the processed data. The input will be left pointing to
+//! data that still needs processing
//!
//! If the parser failed, then there are multiple errors that could be returned.
//! For simplicity, however, in the next chapters we will leave these unexplored.
//!
//! ```text
-//! ┌─► Ok(
-//! │ what the parser didn't touch,
-//! │ what matched the parser
-//! │ )
+//! ┌─► Ok(what matched the parser)
//! ┌─────────┐ │
//! my input───►│my parser├──►either──┤
//! └─────────┘ └─► Err(...)
//! ```
//!
//!
-//! To represent this model of the world, winnow uses the [`IResult<I, O>`] type.
-//! The `Ok` variant has a tuple of `(remainder: I, output: O)`;
+//! To represent this model of the world, winnow uses the [`PResult<O>`] type.
+//! The `Ok` variant has `output: O`;
//! whereas the `Err` variant stores an error.
//!
//! You can import that from:
//!
//! ```rust
-//! use winnow::IResult;
+//! use winnow::PResult;
//! ```
//!
+//! To combine parsers, we need a common way to refer to them which is where the [`Parser<I, O, E>`]
+//! trait comes in with [`Parser::parse_next`] being the primary way to drive
+//! parsing forward.
+//!
//! You'll note that `I` and `O` are parameterized -- while most of the examples in this book
//! will be with `&str` (i.e. parsing a string); they do not have to be strings; nor do they
//! have to be the same type (consider the simple example where `I = &str`, and `O = u64` -- this
//! parses a string into an unsigned integer.)
//!
-//! To combine parsers, we need a common way to refer to them which is where the [`Parser`]
-//! trait comes in with [`Parser::parse_next`] being the primary way to drive
-//! parsing forward.
//!
//! # Let's write our first parser!
//!
//! The simplest parser we can write is one which successfully does nothing.
//!
//! To make it easier to implement a [`Parser`], the trait is implemented for
-//! functions of the form `Fn(I) -> IResult<I, O>`.
+//! functions of the form `Fn(&mut I) -> PResult<O>`.
//!
//! This parser function should take in a `&str`:
//!
@@ -62,27 +58,27 @@
//! - Since it doesn't parse anything, it also should just return an empty string.
//!
//! ```rust
-//! use winnow::IResult;
+//! use winnow::PResult;
//! use winnow::Parser;
//!
-//! pub fn do_nothing_parser(input: &str) -> IResult<&str, &str> {
-//! Ok((input, ""))
+//! pub fn do_nothing_parser<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! Ok("")
//! }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, output) = do_nothing_parser.parse_next(input).unwrap();
+//! let output = do_nothing_parser.parse_next(&mut input).unwrap();
//! // Same as:
-//! // let (remainder, output) = do_nothing_parser(input).unwrap();
+//! // let output = do_nothing_parser(&mut input).unwrap();
//!
-//! assert_eq!(remainder, "0x1a2b Hello");
+//! assert_eq!(input, "0x1a2b Hello");
//! assert_eq!(output, "");
//! }
//! ```
#![allow(unused_imports)]
-use crate::IResult;
+use crate::PResult;
use crate::Parser;
pub use super::chapter_0 as previous;
diff --git a/vendor/winnow/src/_tutorial/chapter_2.rs b/vendor/winnow/src/_tutorial/chapter_2.rs
index 49b61f3f4..b0daedc74 100644
--- a/vendor/winnow/src/_tutorial/chapter_2.rs
+++ b/vendor/winnow/src/_tutorial/chapter_2.rs
@@ -4,54 +4,139 @@
//!
//! ## Tokens
//!
-//! Matching a single token literal is common enough that `Parser` is implemented for
-//! `char`.
-//!
+//! [`Stream`] provides some core operations to help with parsing. For example, to process a
+//! single token, you can do:
//! ```rust
//! # use winnow::Parser;
-//! # use winnow::IResult;
-//! #
-//! fn parse_prefix(input: &str) -> IResult<&str, char> {
-//! '0'.parse_next(input)
+//! # use winnow::PResult;
+//! use winnow::stream::Stream;
+//! use winnow::error::ParserError;
+//! use winnow::error::ErrorKind;
+//! use winnow::error::ErrMode;
+//!
+//! fn parse_prefix(input: &mut &str) -> PResult<char> {
+//! let c = input.next_token().ok_or_else(|| {
+//! ErrMode::from_error_kind(input, ErrorKind::Token)
+//! })?;
+//! if c != '0' {
+//! return Err(ErrMode::from_error_kind(input, ErrorKind::Verify));
+//! }
+//! Ok(c)
//! }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, output) = parse_prefix.parse_next(input).unwrap();
+//! let output = parse_prefix.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, "x1a2b Hello");
+//! assert_eq!(input, "x1a2b Hello");
//! assert_eq!(output, '0');
//!
-//! assert!(parse_prefix("d").is_err());
+//! assert!(parse_prefix.parse_next(&mut "d").is_err());
//! }
//! ```
//!
-//! ## Tags
+//! [`any`] and [`Parser::verify`] are [`Parser`] building blocks on top of [`Stream`]:
+//! ```rust
+//! # use winnow::PResult;
+//! use winnow::Parser;
+//! use winnow::token::any;
//!
-//! One of the most frequent way of matching a token is when they are combined into a string.
-//! Again, this is common enough that `Parser` is implemented for `&str`:
+//! fn parse_prefix(input: &mut &str) -> PResult<char> {
+//! any.verify(|c| *c == '0').parse_next(input)
+//! }
+//! #
+//! # fn main() {
+//! # let mut input = "0x1a2b Hello";
+//! #
+//! # let output = parse_prefix.parse_next(&mut input).unwrap();
+//! #
+//! # assert_eq!(input, "x1a2b Hello");
+//! # assert_eq!(output, '0');
+//! #
+//! # assert!(parse_prefix.parse_next(&mut "d").is_err());
+//! # }
+//! ```
+//!
+//! Matching a single token literal is common enough that [`Parser`] is implemented for
+//! `char`.
//!
//! ```rust
-//! # use winnow::Parser;
-//! # use winnow::IResult;
+//! # use winnow::PResult;
+//! use winnow::Parser;
+//!
+//! fn parse_prefix(input: &mut &str) -> PResult<char> {
+//! '0'.parse_next(input)
+//! }
//! #
-//! fn parse_prefix(input: &str) -> IResult<&str, &str> {
-//! "0x".parse_next(input)
+//! # fn main() {
+//! # let mut input = "0x1a2b Hello";
+//! #
+//! # let output = parse_prefix.parse_next(&mut input).unwrap();
+//! #
+//! # assert_eq!(input, "x1a2b Hello");
+//! # assert_eq!(output, '0');
+//! #
+//! # assert!(parse_prefix.parse_next(&mut "d").is_err());
+//! # }
+//! ```
+//!
+//! ## Tags
+//!
+//! [`Stream`] also supports processing slices of tokens:
+//! ```rust
+//! # use winnow::Parser;
+//! # use winnow::PResult;
+//! use winnow::stream::Stream;
+//! use winnow::error::ParserError;
+//! use winnow::error::ErrorKind;
+//! use winnow::error::ErrMode;
+//!
+//! fn parse_prefix<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! let expected = "0x";
+//! if input.len() < expected.len() {
+//! return Err(ErrMode::from_error_kind(input, ErrorKind::Slice));
+//! }
+//! let actual = input.next_slice(expected.len());
+//! if actual != expected {
+//! return Err(ErrMode::from_error_kind(input, ErrorKind::Verify));
+//! }
+//! Ok(actual)
//! }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, output) = parse_prefix.parse_next(input).unwrap();
-//! assert_eq!(remainder, "1a2b Hello");
+//! let output = parse_prefix.parse_next(&mut input).unwrap();
+//! assert_eq!(input, "1a2b Hello");
//! assert_eq!(output, "0x");
//!
-//! assert!(parse_prefix("0o123").is_err());
+//! assert!(parse_prefix.parse_next(&mut "0o123").is_err());
//! }
//! ```
//!
-//! In `winnow`, we call this type of parser a [`tag`].
+//! Again, matching a literal is common enough that [`Parser`] is implemented for `&str`:
+//! ```rust
+//! # use winnow::PResult;
+//! use winnow::Parser;
+//!
+//! fn parse_prefix<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! "0x".parse_next(input)
+//! }
+//! #
+//! # fn main() {
+//! # let mut input = "0x1a2b Hello";
+//! #
+//! # let output = parse_prefix.parse_next(&mut input).unwrap();
+//! # assert_eq!(input, "1a2b Hello");
+//! # assert_eq!(output, "0x");
+//! #
+//! # assert!(parse_prefix.parse_next(&mut "0o123").is_err());
+//! # }
+//! ```
+//!
+//! In `winnow`, we call this type of parser a [`tag`]. See [`token`] for additional individual
+//! and token-slice parsers.
//!
//! ## Character Classes
//!
@@ -60,21 +145,21 @@
//!
//! ```rust
//! # use winnow::Parser;
-//! # use winnow::IResult;
+//! # use winnow::PResult;
//! use winnow::token::one_of;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, char> {
-//! one_of("0123456789abcdefgABCDEFG").parse_next(input)
+//! fn parse_digits(input: &mut &str) -> PResult<char> {
+//! one_of(('0'..='9', 'a'..='f', 'A'..='F')).parse_next(input)
//! }
//!
//! fn main() {
-//! let input = "1a2b Hello";
+//! let mut input = "1a2b Hello";
//!
-//! let (remainder, output) = parse_digits.parse_next(input).unwrap();
-//! assert_eq!(remainder, "a2b Hello");
+//! let output = parse_digits.parse_next(&mut input).unwrap();
+//! assert_eq!(input, "a2b Hello");
//! assert_eq!(output, '1');
//!
-//! assert!(parse_digits("Z").is_err());
+//! assert!(parse_digits.parse_next(&mut "Z").is_err());
//! }
//! ```
//!
@@ -82,10 +167,10 @@
//! > Let's look at it more closely as its used above (resolving all generic parameters):
//! > ```rust
//! > # use winnow::prelude::*;
-//! > # use winnow::error::Error;
+//! > # use winnow::error::InputError;
//! > pub fn one_of<'i>(
-//! > list: &'static str
-//! > ) -> impl Parser<&'i str, char, Error<&'i str>> {
+//! > list: &'static [char]
+//! > ) -> impl Parser<&'i str, char, InputError<&'i str>> {
//! > // ...
//! > # winnow::token::one_of(list)
//! > }
@@ -93,7 +178,7 @@
//! > If you have not programmed in a language where functions are values, the type signature of the
//! > [`one_of`] function might be a surprise.
//! > The function [`one_of`] *returns a function*. The function it returns is a
-//! > `Parser`, taking a `&str` and returning an `IResult`. This is a common pattern in winnow for
+//! > `Parser`, taking a `&str` and returning an `PResult`. This is a common pattern in winnow for
//! > configurable or stateful parsers.
//!
//! Some of character classes are common enough that a named parser is provided, like with:
@@ -104,48 +189,54 @@
//! You can then capture sequences of these characters with parsers like [`take_while`].
//! ```rust
//! # use winnow::Parser;
-//! # use winnow::IResult;
+//! # use winnow::PResult;
//! use winnow::token::take_while;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, &str> {
-//! take_while(1.., "0123456789abcdefgABCDEFG").parse_next(input)
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! take_while(1.., ('0'..='9', 'a'..='f', 'A'..='F')).parse_next(input)
//! }
//!
//! fn main() {
-//! let input = "1a2b Hello";
+//! let mut input = "1a2b Hello";
//!
-//! let (remainder, output) = parse_digits.parse_next(input).unwrap();
-//! assert_eq!(remainder, " Hello");
+//! let output = parse_digits.parse_next(&mut input).unwrap();
+//! assert_eq!(input, " Hello");
//! assert_eq!(output, "1a2b");
//!
-//! assert!(parse_digits("Z").is_err());
+//! assert!(parse_digits.parse_next(&mut "Z").is_err());
//! }
//! ```
//!
//! We could simplify this further with by using one of the built-in character classes, [`hex_digit1`]:
//! ```rust
//! # use winnow::Parser;
-//! # use winnow::IResult;
+//! # use winnow::PResult;
//! use winnow::ascii::hex_digit1;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, &str> {
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! hex_digit1.parse_next(input)
//! }
//!
//! fn main() {
-//! let input = "1a2b Hello";
+//! let mut input = "1a2b Hello";
//!
-//! let (remainder, output) = parse_digits.parse_next(input).unwrap();
-//! assert_eq!(remainder, " Hello");
+//! let output = parse_digits.parse_next(&mut input).unwrap();
+//! assert_eq!(input, " Hello");
//! assert_eq!(output, "1a2b");
//!
-//! assert!(parse_digits("Z").is_err());
+//! assert!(parse_digits.parse_next(&mut "Z").is_err());
//! }
//! ```
+//!
+//! See [`ascii`] for more text-based parsers.
#![allow(unused_imports)]
+use crate::ascii;
use crate::ascii::hex_digit1;
use crate::stream::ContainsToken;
+use crate::stream::Stream;
+use crate::token;
+use crate::token::any;
use crate::token::one_of;
use crate::token::tag;
use crate::token::take_while;
diff --git a/vendor/winnow/src/_tutorial/chapter_3.rs b/vendor/winnow/src/_tutorial/chapter_3.rs
index 8d307e324..83714f4d7 100644
--- a/vendor/winnow/src/_tutorial/chapter_3.rs
+++ b/vendor/winnow/src/_tutorial/chapter_3.rs
@@ -10,15 +10,14 @@
//! Now that we can create more interesting parsers, we can sequence them together, like:
//!
//! ```rust
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
-//! # use winnow::Parser;
-//! # use winnow::IResult;
//! #
-//! fn parse_prefix(input: &str) -> IResult<&str, &str> {
+//! fn parse_prefix<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! "0x".parse_next(input)
//! }
//!
-//! fn parse_digits(input: &str) -> IResult<&str, &str> {
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! take_while(1.., (
//! ('0'..='9'),
//! ('A'..='F'),
@@ -27,28 +26,27 @@
//! }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, prefix) = parse_prefix.parse_next(input).unwrap();
-//! let (remainder, digits) = parse_digits.parse_next(remainder).unwrap();
+//! let prefix = parse_prefix.parse_next(&mut input).unwrap();
+//! let digits = parse_digits.parse_next(&mut input).unwrap();
//!
//! assert_eq!(prefix, "0x");
//! assert_eq!(digits, "1a2b");
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! }
//! ```
//!
//! To sequence these together, you can just put them in a tuple:
//! ```rust
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
-//! # use winnow::Parser;
-//! # use winnow::IResult;
//! #
-//! # fn parse_prefix(input: &str) -> IResult<&str, &str> {
+//! # fn parse_prefix<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # "0x".parse_next(input)
//! # }
//! #
-//! # fn parse_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -59,32 +57,31 @@
//! //...
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, (prefix, digits)) = (
+//! let (prefix, digits) = (
//! parse_prefix,
//! parse_digits
-//! ).parse_next(input).unwrap();
+//! ).parse_next(&mut input).unwrap();
//!
//! assert_eq!(prefix, "0x");
//! assert_eq!(digits, "1a2b");
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! }
//! ```
//!
//! Frequently, you won't care about the tag and you can instead use one of the provided combinators,
//! like [`preceded`]:
//! ```rust
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
-//! # use winnow::Parser;
-//! # use winnow::IResult;
//! use winnow::combinator::preceded;
//!
-//! # fn parse_prefix(input: &str) -> IResult<&str, &str> {
+//! # fn parse_prefix<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # "0x".parse_next(input)
//! # }
//! #
-//! # fn parse_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -95,63 +92,72 @@
//! //...
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, digits) = preceded(
+//! let digits = preceded(
//! parse_prefix,
//! parse_digits
-//! ).parse_next(input).unwrap();
+//! ).parse_next(&mut input).unwrap();
//!
//! assert_eq!(digits, "1a2b");
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! }
//! ```
//!
+//! See [`combinator`] for more sequencing parsers.
+//!
//! ## Alternatives
//!
//! Sometimes, we might want to choose between two parsers; and we're happy with
//! either being used.
//!
-//! The de facto way to do this in winnow is with the [`alt()`] combinator which will execute each
-//! parser in a tuple until it finds one that does not error. If all error, then by default you are
-//! given the error from the last parser.
-//!
-//! We can see a basic example of `alt()` below.
+//! [`Stream::checkpoint`] helps us to retry parsing:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
-//! use winnow::combinator::alt;
+//! use winnow::stream::Stream;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, (&str, &str)> {
-//! alt((
-//! ("0b", parse_bin_digits),
-//! ("0o", parse_oct_digits),
-//! ("0d", parse_dec_digits),
-//! ("0x", parse_hex_digits),
-//! )).parse_next(input)
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<(&'s str, &'s str)> {
+//! let start = input.checkpoint();
+//!
+//! if let Ok(output) = ("0b", parse_bin_digits).parse_next(input) {
+//! return Ok(output);
+//! }
+//!
+//! input.reset(start);
+//! if let Ok(output) = ("0o", parse_oct_digits).parse_next(input) {
+//! return Ok(output);
+//! }
+//!
+//! input.reset(start);
+//! if let Ok(output) = ("0d", parse_dec_digits).parse_next(input) {
+//! return Ok(output);
+//! }
+//!
+//! input.reset(start);
+//! ("0x", parse_hex_digits).parse_next(input)
//! }
//!
//! // ...
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -160,31 +166,147 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, (prefix, digits)) = parse_digits.parse_next(input).unwrap();
+//! let (prefix, digits) = parse_digits.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(prefix, "0x");
//! assert_eq!(digits, "1a2b");
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
//!
+//! > **Warning:** the above example is for illustrative purposes and relying on `Result::Ok` or
+//! > `Result::Err` can lead to incorrect behavior. This will be clarified in later when covering
+//! > [error handling][`chapter_6`#errmode]
+//!
+//! [`opt`] is a basic building block for correctly handling retrying parsing:
+//! ```rust
+//! # use winnow::prelude::*;
+//! # use winnow::token::take_while;
+//! use winnow::combinator::opt;
+//!
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<(&'s str, &'s str)> {
+//! if let Some(output) = opt(("0b", parse_bin_digits)).parse_next(input)? {
+//! Ok(output)
+//! } else if let Some(output) = opt(("0o", parse_oct_digits)).parse_next(input)? {
+//! Ok(output)
+//! } else if let Some(output) = opt(("0d", parse_dec_digits)).parse_next(input)? {
+//! Ok(output)
+//! } else {
+//! ("0x", parse_hex_digits).parse_next(input)
+//! }
+//! }
+//! #
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # ('A'..='F'),
+//! # ('a'..='f'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn main() {
+//! # let mut input = "0x1a2b Hello";
+//! #
+//! # let (prefix, digits) = parse_digits.parse_next(&mut input).unwrap();
+//! #
+//! # assert_eq!(input, " Hello");
+//! # assert_eq!(prefix, "0x");
+//! # assert_eq!(digits, "1a2b");
+//! #
+//! # assert!(parse_digits(&mut "ghiWorld").is_err());
+//! # }
+//! ```
+//!
+//! [`alt`] encapsulates this if/else-if ladder pattern, with the last case being the `else`:
+//! ```rust
+//! # use winnow::prelude::*;
+//! # use winnow::token::take_while;
+//! use winnow::combinator::alt;
+//!
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<(&'s str, &'s str)> {
+//! alt((
+//! ("0b", parse_bin_digits),
+//! ("0o", parse_oct_digits),
+//! ("0d", parse_dec_digits),
+//! ("0x", parse_hex_digits),
+//! )).parse_next(input)
+//! }
+//! #
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # ('A'..='F'),
+//! # ('a'..='f'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn main() {
+//! # let mut input = "0x1a2b Hello";
+//! #
+//! # let (prefix, digits) = parse_digits.parse_next(&mut input).unwrap();
+//! #
+//! # assert_eq!(input, " Hello");
+//! # assert_eq!(prefix, "0x");
+//! # assert_eq!(digits, "1a2b");
+//! #
+//! # assert!(parse_digits(&mut "ghiWorld").is_err());
+//! # }
+//! ```
+//!
+//! > **Note:** [`success`] and [`fail`] are parsers that might be useful in the `else` case.
+//!
//! Sometimes a giant if/else-if ladder can be slow and you'd rather have a `match` statement for
//! branches of your parser that have unique prefixes. In this case, you can use the
//! [`dispatch`][crate::combinator::dispatch] macro:
//!
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! use winnow::combinator::dispatch;
//! use winnow::token::take;
//! use winnow::combinator::fail;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, &str> {
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! dispatch!(take(2usize);
//! "0b" => parse_bin_digits,
//! "0o" => parse_oct_digits,
@@ -195,25 +317,25 @@
//! }
//!
//! // ...
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -222,21 +344,32 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, digits) = parse_digits.parse_next(input).unwrap();
+//! let digits = parse_digits.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(digits, "1a2b");
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
+//!
+//! > **Note:** [`peek`] may be useful when [`dispatch`]ing from hints from each case's parser.
+//!
+//! See [`combinator`] for more alternative parsers.
#![allow(unused_imports)]
+use super::chapter_6;
+use crate::combinator;
use crate::combinator::alt;
use crate::combinator::dispatch;
+use crate::combinator::fail;
+use crate::combinator::opt;
+use crate::combinator::peek;
use crate::combinator::preceded;
+use crate::combinator::success;
+use crate::stream::Stream;
pub use super::chapter_2 as previous;
pub use super::chapter_4 as next;
diff --git a/vendor/winnow/src/_tutorial/chapter_4.rs b/vendor/winnow/src/_tutorial/chapter_4.rs
index 315d185ba..fb14613f3 100644
--- a/vendor/winnow/src/_tutorial/chapter_4.rs
+++ b/vendor/winnow/src/_tutorial/chapter_4.rs
@@ -1,18 +1,18 @@
//! # Chapter 4: Parsers With Custom Return Types
//!
//! So far, we have seen mostly functions that take an `&str`, and return a
-//! `IResult<&str, &str>`. Splitting strings into smaller strings and characters is certainly
+//! `PResult<&str>`. Splitting strings into smaller strings and characters is certainly
//! useful, but it's not the only thing winnow is capable of!
//!
//! A useful operation when parsing is to convert between types; for example
//! parsing from `&str` to another primitive, like [`usize`].
//!
//! All we need to do for our parser to return a different type is to change
-//! the second type parameter of [`IResult`] to the desired return type.
-//! For example, to return a `usize`, return a `IResult<&str, usize>`.
-//! Recall that the first type parameter of the `IResult` is the input
+//! the type parameter of [`PResult`] to the desired return type.
+//! For example, to return a `usize`, return a `PResult<usize>`.
+//! Recall that the type parameter of the `PResult` is the input
//! type, so even if you're returning something different, if your input
-//! is a `&str`, the first type argument of `IResult` should be also.
+//! is a `&str`, the type argument of `PResult` should be also.
//!
//! One winnow-native way of doing a type conversion is to use the
//! [`Parser::parse_to`] combinator
@@ -20,38 +20,36 @@
//!
//! The following code converts from a string containing a number to `usize`:
//! ```rust
-//! # use winnow::Parser;
-//! # use winnow::IResult;
+//! # use winnow::prelude::*;
//! # use winnow::ascii::digit1;
//! #
-//! fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! fn parse_digits(input: &mut &str) -> PResult<usize> {
//! digit1
//! .parse_to()
//! .parse_next(input)
//! }
//!
//! fn main() {
-//! let input = "1024 Hello";
+//! let mut input = "1024 Hello";
//!
-//! let (remainder, output) = parse_digits.parse_next(input).unwrap();
-//! assert_eq!(remainder, " Hello");
+//! let output = parse_digits.parse_next(&mut input).unwrap();
+//! assert_eq!(input, " Hello");
//! assert_eq!(output, 1024);
//!
-//! assert!(parse_digits("Z").is_err());
+//! assert!(parse_digits(&mut "Z").is_err());
//! }
//! ```
//!
//! `Parser::parse_to` is just a convenient form of [`Parser::try_map`] which we can use to handle
//! all radices of numbers:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! use winnow::combinator::dispatch;
//! use winnow::token::take;
//! use winnow::combinator::fail;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! fn parse_digits(input: &mut &str) -> PResult<usize> {
//! dispatch!(take(2usize);
//! "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
//! "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
@@ -62,25 +60,25 @@
//! }
//!
//! // ...
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -89,19 +87,21 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, digits) = parse_digits.parse_next(input).unwrap();
+//! let digits = parse_digits.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(digits, 0x1a2b);
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
+//!
+//! See also [`Parser`] for more output-modifying parsers.
#![allow(unused_imports)]
-use crate::IResult;
+use crate::PResult;
use crate::Parser;
use std::str::FromStr;
diff --git a/vendor/winnow/src/_tutorial/chapter_5.rs b/vendor/winnow/src/_tutorial/chapter_5.rs
index 3a4be4b32..95a89dc8c 100644
--- a/vendor/winnow/src/_tutorial/chapter_5.rs
+++ b/vendor/winnow/src/_tutorial/chapter_5.rs
@@ -1,12 +1,11 @@
//! # Chapter 5: Repetition
//!
//! In [`chapter_3`], we covered how to sequence different parsers into a tuple but sometimes you need to run a
-//! single parser multiple times, collecting the result into a [`Vec`].
+//! single parser multiple times, collecting the result into a container, like [`Vec`].
//!
-//! Let's take our `parse_digits` and collect a list of them with [`repeat`]:
+//! Let's collect the result of `parse_digits`:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::dispatch;
//! # use winnow::token::take;
@@ -15,40 +14,44 @@
//! use winnow::combinator::repeat;
//! use winnow::combinator::terminated;
//!
-//! fn parse_list(input: &str) -> IResult<&str, Vec<usize>> {
-//! repeat(0.., terminated(parse_digits, opt(','))).parse_next(input)
+//! fn parse_list(input: &mut &str) -> PResult<Vec<usize>> {
+//! let mut list = Vec::new();
+//! while let Some(output) = opt(terminated(parse_digits, opt(','))).parse_next(input)? {
+//! list.push(output);
+//! }
+//! Ok(list)
//! }
//!
//! // ...
-//! # fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! # fn parse_digits(input: &mut &str) -> PResult<usize> {
//! # dispatch!(take(2usize);
-//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
-//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
-//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
-//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
-//! # _ => fail,
-//! # ).parse_next(input)
+//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
+//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
+//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
+//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
+//! # _ => fail,
+//! # ).parse_next(input)
//! # }
//! #
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -57,62 +60,126 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b,0x3c4d,0x5e6f Hello";
+//! let mut input = "0x1a2b,0x3c4d,0x5e6f Hello";
//!
-//! let (remainder, digits) = parse_list.parse_next(input).unwrap();
+//! let digits = parse_list.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(digits, vec![0x1a2b, 0x3c4d, 0x5e6f]);
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
//!
+//! We can implement this declaratively with [`repeat`]:
+//! ```rust
+//! # use winnow::prelude::*;
+//! # use winnow::token::take_while;
+//! # use winnow::combinator::dispatch;
+//! # use winnow::token::take;
+//! # use winnow::combinator::fail;
+//! use winnow::combinator::opt;
+//! use winnow::combinator::repeat;
+//! use winnow::combinator::terminated;
+//!
+//! fn parse_list(input: &mut &str) -> PResult<Vec<usize>> {
+//! repeat(0..,
+//! terminated(parse_digits, opt(','))
+//! ).parse_next(input)
+//! }
+//! #
+//! # fn parse_digits(input: &mut &str) -> PResult<usize> {
+//! # dispatch!(take(2usize);
+//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
+//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
+//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
+//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
+//! # _ => fail,
+//! # ).parse_next(input)
+//! # }
+//! #
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='7'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! # take_while(1.., (
+//! # ('0'..='9'),
+//! # ('A'..='F'),
+//! # ('a'..='f'),
+//! # )).parse_next(input)
+//! # }
+//! #
+//! # fn main() {
+//! # let mut input = "0x1a2b,0x3c4d,0x5e6f Hello";
+//! #
+//! # let digits = parse_list.parse_next(&mut input).unwrap();
+//! #
+//! # assert_eq!(input, " Hello");
+//! # assert_eq!(digits, vec![0x1a2b, 0x3c4d, 0x5e6f]);
+//! #
+//! # assert!(parse_digits(&mut "ghiWorld").is_err());
+//! # }
+//! ```
+//!
//! You'll notice that the above allows trailing `,` when we intended to not support that. We can
//! easily fix this by using [`separated0`]:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::dispatch;
//! # use winnow::token::take;
//! # use winnow::combinator::fail;
//! use winnow::combinator::separated0;
//!
-//! fn parse_list(input: &str) -> IResult<&str, Vec<usize>> {
+//! fn parse_list(input: &mut &str) -> PResult<Vec<usize>> {
//! separated0(parse_digits, ",").parse_next(input)
//! }
//!
//! // ...
-//! # fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! # fn parse_digits(input: &mut &str) -> PResult<usize> {
//! # dispatch!(take(2usize);
-//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
-//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
-//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
-//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
-//! # _ => fail,
-//! # ).parse_next(input)
+//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
+//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
+//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
+//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
+//! # _ => fail,
+//! # ).parse_next(input)
//! # }
//! #
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -121,14 +188,14 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b,0x3c4d,0x5e6f Hello";
+//! let mut input = "0x1a2b,0x3c4d,0x5e6f Hello";
//!
-//! let (remainder, digits) = parse_list.parse_next(input).unwrap();
+//! let digits = parse_list.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(digits, vec![0x1a2b, 0x3c4d, 0x5e6f]);
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
//!
@@ -136,52 +203,50 @@
//! [`Accumulate`] to gather the results. This let's us make more complex parsers than we did in
//! [`chapter_2`] by accumulating the results into a `()` and [`recognize`][Parser::recognize]-ing the captured input:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::dispatch;
//! # use winnow::token::take;
//! # use winnow::combinator::fail;
//! # use winnow::combinator::separated0;
//! #
-//! fn recognize_list(input: &str) -> IResult<&str, &str> {
+//! fn recognize_list<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! parse_list.recognize().parse_next(input)
//! }
//!
-//! fn parse_list(input: &str) -> IResult<&str, ()> {
+//! fn parse_list(input: &mut &str) -> PResult<()> {
//! separated0(parse_digits, ",").parse_next(input)
//! }
//!
-//! // ...
-//! # fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! # fn parse_digits(input: &mut &str) -> PResult<usize> {
//! # dispatch!(take(2usize);
-//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
-//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
-//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
-//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
-//! # _ => fail,
-//! # ).parse_next(input)
+//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
+//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
+//! # "0d" => parse_dec_digits.try_map(|s| usize::from_str_radix(s, 10)),
+//! # "0x" => parse_hex_digits.try_map(|s| usize::from_str_radix(s, 16)),
+//! # _ => fail,
+//! # ).parse_next(input)
//! # }
//! #
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -190,20 +255,22 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b,0x3c4d,0x5e6f Hello";
+//! let mut input = "0x1a2b,0x3c4d,0x5e6f Hello";
//!
-//! let (remainder, digits) = recognize_list.parse_next(input).unwrap();
+//! let digits = recognize_list.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(digits, "0x1a2b,0x3c4d,0x5e6f");
//!
-//! assert!(parse_digits("ghiWorld").is_err());
+//! assert!(parse_digits(&mut "ghiWorld").is_err());
//! }
//! ```
+//! See [`combinator`] for more repetition parsers.
#![allow(unused_imports)]
use super::chapter_2;
use super::chapter_3;
+use crate::combinator;
use crate::combinator::repeat;
use crate::combinator::separated0;
use crate::stream::Accumulate;
diff --git a/vendor/winnow/src/_tutorial/chapter_6.rs b/vendor/winnow/src/_tutorial/chapter_6.rs
index 268e38a31..d7d2c9fc8 100644
--- a/vendor/winnow/src/_tutorial/chapter_6.rs
+++ b/vendor/winnow/src/_tutorial/chapter_6.rs
@@ -2,51 +2,48 @@
//!
//! ## `Error`
//!
-//! Back in [`chapter_1`], we glossed over the `Err` side of [`IResult`]. `IResult<I, O>` is
-//! actually short for `IResult<I, O, E=Error>` where [`Error`] is a cheap, universal error type
-//! for getting started. When humans are producing the file, like with `toml`, you might want to
-//! sacrifice some performance for providing more details on how to resolve the problem
+//! Back in [`chapter_1`], we glossed over the `Err` side of [`PResult`]. `PResult<O>` is
+//! actually short for `PResult<O, E=ContextError>` where [`ContextError`] is a relatively cheap
+//! way of building up reasonable errors for humans.
//!
-//! winnow includes [`VerboseError`] for this but you can [customize the error as you
-//! wish][_topic::error]. You can use [`Parser::context`] to annotate the error with custom types
+//! You can use [`Parser::context`] to annotate the error with custom types
//! while unwinding to further improve the error quality.
//!
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::alt;
-//! use winnow::error::VerboseError;
+//! use winnow::error::StrContext;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, (&str, &str), VerboseError<&str>> {
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<(&'s str, &'s str)> {
//! alt((
-//! ("0b", parse_bin_digits).context("binary"),
-//! ("0o", parse_oct_digits).context("octal"),
-//! ("0d", parse_dec_digits).context("decimal"),
-//! ("0x", parse_hex_digits).context("hexadecimal"),
+//! ("0b", parse_bin_digits).context(StrContext::Label("binary")),
+//! ("0o", parse_oct_digits).context(StrContext::Label("octal")),
+//! ("0d", parse_dec_digits).context(StrContext::Label("decimal")),
+//! ("0x", parse_hex_digits).context(StrContext::Label("hexadecimal")),
//! )).parse_next(input)
//! }
//!
//! // ...
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -55,11 +52,11 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, (prefix, digits)) = parse_digits.parse_next(input).unwrap();
+//! let (prefix, digits) = parse_digits.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(prefix, "0x");
//! assert_eq!(digits, "1a2b");
//! }
@@ -71,58 +68,57 @@
//!
//! ## `ErrMode`
//!
-//! Let's break down `IResult<I, O, E>` one step further:
+//! Let's break down `PResult<O, E>` one step further:
//! ```rust
-//! # use winnow::error::Error;
+//! # use winnow::error::ErrorKind;
//! # use winnow::error::ErrMode;
-//! pub type IResult<I, O, E = Error<I>> = Result<(I, O), ErrMode<E>>;
+//! pub type OResult<O, E = ErrorKind> = Result<O, ErrMode<E>>;
//! ```
-//! `IResult` is just a fancy wrapper around `Result` that wraps our error in an [`ErrMode`]
+//! [`PResult`] is just a fancy wrapper around `Result` that wraps our error in an [`ErrMode`]
//! type.
//!
-//! `ErrMode` is an enum with `Backtrack` and `Cut` variants (ignore `Incomplete` as its only
-//! relevant for [streaming][_topic::stream]). By default, errors are `Backtrack`, meaning that
-//! other parsing branches will be attempted on failure, like the next case of an `alt`. `Cut`
+//! [`ErrMode`] is an enum with [`Backtrack`] and [`Cut`] variants (ignore [`Incomplete`] as its only
+//! relevant for [streaming][_topic::stream]). By default, errors are [`Backtrack`], meaning that
+//! other parsing branches will be attempted on failure, like the next case of an [`alt`]. [`Cut`]
//! shortcircuits all other branches, immediately reporting the error.
//!
//! So we can get the correct `context` by modifying the above example with [`cut_err`]:
//! ```rust
-//! # use winnow::IResult;
-//! # use winnow::Parser;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::alt;
-//! # use winnow::error::VerboseError;
+//! # use winnow::error::StrContext;
//! use winnow::combinator::cut_err;
//!
-//! fn parse_digits(input: &str) -> IResult<&str, (&str, &str), VerboseError<&str>> {
+//! fn parse_digits<'s>(input: &mut &'s str) -> PResult<(&'s str, &'s str)> {
//! alt((
-//! ("0b", cut_err(parse_bin_digits)).context("binary"),
-//! ("0o", cut_err(parse_oct_digits)).context("octal"),
-//! ("0d", cut_err(parse_dec_digits)).context("decimal"),
-//! ("0x", cut_err(parse_hex_digits)).context("hexadecimal"),
+//! ("0b", cut_err(parse_bin_digits)).context(StrContext::Label("binary")),
+//! ("0o", cut_err(parse_oct_digits)).context(StrContext::Label("octal")),
+//! ("0d", cut_err(parse_dec_digits)).context(StrContext::Label("decimal")),
+//! ("0x", cut_err(parse_hex_digits)).context(StrContext::Label("hexadecimal")),
//! )).parse_next(input)
//! }
//!
//! // ...
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -131,11 +127,11 @@
//! # }
//!
//! fn main() {
-//! let input = "0x1a2b Hello";
+//! let mut input = "0x1a2b Hello";
//!
-//! let (remainder, (prefix, digits)) = parse_digits.parse_next(input).unwrap();
+//! let (prefix, digits) = parse_digits.parse_next(&mut input).unwrap();
//!
-//! assert_eq!(remainder, " Hello");
+//! assert_eq!(input, " Hello");
//! assert_eq!(prefix, "0x");
//! assert_eq!(digits, "1a2b");
//! }
@@ -147,10 +143,11 @@ use super::chapter_1;
use super::chapter_3;
use crate::combinator::alt;
use crate::combinator::cut_err;
+use crate::error::ContextError;
use crate::error::ErrMode;
-use crate::error::Error;
-use crate::error::VerboseError;
-use crate::IResult;
+use crate::error::ErrMode::*;
+use crate::error::ErrorKind;
+use crate::PResult;
use crate::Parser;
use crate::_topic;
diff --git a/vendor/winnow/src/_tutorial/chapter_7.rs b/vendor/winnow/src/_tutorial/chapter_7.rs
index c20607c36..45f2d2d2a 100644
--- a/vendor/winnow/src/_tutorial/chapter_7.rs
+++ b/vendor/winnow/src/_tutorial/chapter_7.rs
@@ -3,53 +3,62 @@
//! So far, we've highlighted how to incrementally parse, but how do we bring this all together
//! into our application?
//!
-//! The type we've been working with looks like:
+//! Parsers we've been working with look like:
//! ```rust
-//! # use winnow::error::VerboseError;
+//! # use winnow::error::ContextError;
//! # use winnow::error::ErrMode;
-//! type IResult<'i, O> = Result<
-//! (&'i str, O),
-//! ErrMode<
-//! VerboseError<&'i str>
-//! >
+//! # use winnow::Parser;
+//! #
+//! pub fn parser<'s>(input: &mut &'s str) -> PResult<&'s str> {
+//! // ...
+//! # Ok("")
+//! }
+//!
+//! type PResult<O> = Result<
+//! O,
+//! ErrMode<ContextError>
//! >;
//! ```
-//! 1. We have to decide what to do about the `remainder` of the input.
-//! 2. The error type is not compatible with the rest of the Rust ecosystem
+//! 1. We have to decide what to do about the "remainder" of the `input`.
+//! 2. The [`ErrMode<ContextError>`] is not compatible with the rest of the Rust ecosystem.
+//! Normally, Rust applications want errors that are `std::error::Error + Send + Sync + 'static`
+//! meaning:
+//! - They implement the [`std::error::Error`] trait
+//! - They can be sent across threads
+//! - They are safe to be referenced across threads
+//! - They do not borrow
//!
-//! Normally, Rust applications want errors that are `std::error::Error + Send + Sync + 'static`
-//! meaning:
-//! - They implement the [`std::error::Error`] trait
-//! - They can be sent across threads
-//! - They are safe to be referenced across threads
-//! - They do not borrow
-//!
-//! winnow provides some helpers for this:
+//! winnow provides [`Parser::parse`] to help with this:
+//! - Ensures we hit [`eof`]
+//! - Removes the [`ErrMode`] wrapper
+//! - Wraps the error in [`ParseError`]
+//! - Provides access to the original [`input`][ParseError::input] with the
+//! [`offset`][ParseError::offset] of where it failed
+//! - Provides a default renderer (via [`std::fmt::Display`])
//! ```rust
-//! # use winnow::IResult;
+//! # use winnow::prelude::*;
//! # use winnow::token::take_while;
//! # use winnow::combinator::dispatch;
//! # use winnow::token::take;
//! # use winnow::combinator::fail;
//! use winnow::Parser;
-//! use winnow::error::Error;
//!
//! #[derive(Debug, PartialEq, Eq)]
//! pub struct Hex(usize);
//!
//! impl std::str::FromStr for Hex {
-//! type Err = Error<String>;
+//! type Err = String;
//!
//! fn from_str(input: &str) -> Result<Self, Self::Err> {
//! parse_digits
//! .map(Hex)
//! .parse(input)
-//! .map_err(|e| e.into_owned())
+//! .map_err(|e| e.to_string())
//! }
//! }
//!
//! // ...
-//! # fn parse_digits(input: &str) -> IResult<&str, usize> {
+//! # fn parse_digits<'s>(input: &mut &'s str) -> PResult<usize> {
//! # dispatch!(take(2usize);
//! # "0b" => parse_bin_digits.try_map(|s| usize::from_str_radix(s, 2)),
//! # "0o" => parse_oct_digits.try_map(|s| usize::from_str_radix(s, 8)),
@@ -59,25 +68,25 @@
//! # ).parse_next(input)
//! # }
//! #
-//! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_bin_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_oct_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='7'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_dec_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # )).parse_next(input)
//! # }
//! #
-//! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> {
+//! # fn parse_hex_digits<'s>(input: &mut &'s str) -> PResult<&'s str> {
//! # take_while(1.., (
//! # ('0'..='9'),
//! # ('A'..='F'),
@@ -95,17 +104,14 @@
//! assert!(input.parse::<Hex>().is_err());
//! }
//! ```
-//! - Ensures we hit [`eof`]
-//! - Removes the [`ErrMode`] wrapper
-//!
-//! [`Error::into_owned`]:
-//! - Converts the `&str` in `Error` to `String` which enables support for [`std::error::Error`]
#![allow(unused_imports)]
use super::chapter_1;
use crate::combinator::eof;
use crate::error::ErrMode;
-use crate::error::Error;
-use crate::IResult;
+use crate::error::InputError;
+use crate::error::ParseError;
+use crate::PResult;
+use crate::Parser;
pub use super::chapter_6 as previous;