diff options
Diffstat (limited to 'vendor/winnow/src')
43 files changed, 5303 insertions, 4226 deletions
diff --git a/vendor/winnow/src/_topic/language.rs b/vendor/winnow/src/_topic/language.rs index d257c0b18..245bab4c7 100644 --- a/vendor/winnow/src/_topic/language.rs +++ b/vendor/winnow/src/_topic/language.rs @@ -28,8 +28,8 @@ //! use winnow::prelude::*; //! use winnow::{ //! error::ParseError, -//! sequence::delimited, -//! character::multispace0, +//! combinator::delimited, +//! ascii::multispace0, //! }; //! //! /// A combinator that takes a parser `inner` and produces a parser that also consumes both leading and @@ -62,7 +62,7 @@ //! use winnow::prelude::*; //! use winnow::{ //! error::ParseError, -//! bytes::take_till1, +//! token::take_till1, //! }; //! //! pub fn peol_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, (), E> @@ -82,7 +82,7 @@ //! use winnow::prelude::*; //! use winnow::{ //! error::ParseError, -//! bytes::{tag, take_until0}, +//! token::{tag, take_until0}, //! }; //! //! pub fn pinline_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, (), E> { @@ -107,14 +107,14 @@ //! use winnow::prelude::*; //! use winnow::{ //! stream::AsChar, -//! bytes::take_while0, -//! bytes::one_of, +//! token::take_while, +//! token::one_of, //! }; //! //! pub fn identifier(input: &str) -> IResult<&str, &str> { //! ( //! one_of(|c: char| c.is_alpha() || c == '_'), -//! take_while0(|c: char| c.is_alphanum() || c == '_') +//! take_while(0.., |c: char| c.is_alphanum() || c == '_') //! ) //! .recognize() //! .parse_next(input) @@ -122,8 +122,8 @@ //! ``` //! //! Let's say we apply this to the identifier `hello_world123abc`. The first element of the tuple -//! would uses [`one_of`][crate::bytes::one_of] which would recognize `h`. The tuple ensures that -//! `ello_world123abc` will be piped to the next [`take_while0`][crate::bytes::take_while0] parser, +//! would uses [`one_of`][crate::token::one_of] which would recognize `h`. The tuple ensures that +//! `ello_world123abc` will be piped to the next [`take_while`][crate::token::take_while] parser, //! which recognizes every remaining character. However, the tuple returns a tuple of the results //! of its sub-parsers. The [`recognize`][crate::Parser::recognize] parser produces a `&str` of the //! input text that was parsed, which in this case is the entire `&str` `hello_world123abc`. @@ -146,9 +146,6 @@ //! string slice to an integer value is slightly simpler. You can also strip the `_` from the string //! slice that is returned, which is demonstrated in the second hexadecimal number parser. //! -//! If you wish to limit the number of digits in a valid integer literal, replace `many1` with -//! `many_m_n` in the recipes. -//! //! #### Hexadecimal //! //! The parser outputs the string slice of the digits without the leading `0x`/`0X`. @@ -156,18 +153,18 @@ //! ```rust //! use winnow::prelude::*; //! use winnow::{ -//! branch::alt, -//! multi::{many0, many1}, -//! sequence::{preceded, terminated}, -//! bytes::one_of, -//! bytes::tag, +//! combinator::alt, +//! combinator::{repeat}, +//! combinator::{preceded, terminated}, +//! token::one_of, +//! token::tag, //! }; //! //! fn hexadecimal(input: &str) -> IResult<&str, &str> { // <'a, E: ParseError<&'a str>> //! preceded( //! alt(("0x", "0X")), -//! many1( -//! terminated(one_of("0123456789abcdefABCDEF"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("0123456789abcdefABCDEF"), repeat(0.., '_').map(|()| ())) //! ).map(|()| ()).recognize() //! ).parse_next(input) //! } @@ -178,20 +175,20 @@ //! ```rust //! use winnow::prelude::*; //! use winnow::{ -//! branch::alt, -//! multi::{many0, many1}, -//! sequence::{preceded, terminated}, -//! bytes::one_of, -//! bytes::tag, +//! combinator::alt, +//! combinator::{repeat}, +//! combinator::{preceded, terminated}, +//! token::one_of, +//! token::tag, //! }; //! //! fn hexadecimal_value(input: &str) -> IResult<&str, i64> { //! preceded( //! alt(("0x", "0X")), -//! many1( -//! terminated(one_of("0123456789abcdefABCDEF"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("0123456789abcdefABCDEF"), repeat(0.., '_').map(|()| ())) //! ).map(|()| ()).recognize() -//! ).map_res( +//! ).try_map( //! |out: &str| i64::from_str_radix(&str::replace(&out, "_", ""), 16) //! ).parse_next(input) //! } @@ -202,18 +199,18 @@ //! ```rust //! use winnow::prelude::*; //! use winnow::{ -//! branch::alt, -//! multi::{many0, many1}, -//! sequence::{preceded, terminated}, -//! bytes::one_of, -//! bytes::tag, +//! combinator::alt, +//! combinator::{repeat}, +//! combinator::{preceded, terminated}, +//! token::one_of, +//! token::tag, //! }; //! //! fn octal(input: &str) -> IResult<&str, &str> { //! preceded( //! alt(("0o", "0O")), -//! many1( -//! terminated(one_of("01234567"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("01234567"), repeat(0.., '_').map(|()| ())) //! ).map(|()| ()).recognize() //! ).parse_next(input) //! } @@ -224,18 +221,18 @@ //! ```rust //! use winnow::prelude::*; //! use winnow::{ -//! branch::alt, -//! multi::{many0, many1}, -//! sequence::{preceded, terminated}, -//! bytes::one_of, -//! bytes::tag, +//! combinator::alt, +//! combinator::{repeat}, +//! combinator::{preceded, terminated}, +//! token::one_of, +//! token::tag, //! }; //! //! fn binary(input: &str) -> IResult<&str, &str> { //! preceded( //! alt(("0b", "0B")), -//! many1( -//! terminated(one_of("01"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("01"), repeat(0.., '_').map(|()| ())) //! ).map(|()| ()).recognize() //! ).parse_next(input) //! } @@ -247,14 +244,14 @@ //! use winnow::prelude::*; //! use winnow::{ //! IResult, -//! multi::{many0, many1}, -//! sequence::terminated, -//! bytes::one_of, +//! combinator::{repeat}, +//! combinator::terminated, +//! token::one_of, //! }; //! //! fn decimal(input: &str) -> IResult<&str, &str> { -//! many1( -//! terminated(one_of("0123456789"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("0123456789"), repeat(0.., '_').map(|()| ())) //! ).map(|()| ()) //! .recognize() //! .parse_next(input) @@ -268,11 +265,11 @@ //! ```rust //! use winnow::prelude::*; //! use winnow::{ -//! branch::alt, -//! multi::{many0, many1}, +//! combinator::alt, +//! combinator::{repeat}, //! combinator::opt, -//! sequence::{preceded, terminated}, -//! bytes::one_of, +//! combinator::{preceded, terminated}, +//! token::one_of, //! }; //! //! fn float(input: &str) -> IResult<&str, &str> { @@ -308,8 +305,8 @@ //! } //! //! fn decimal(input: &str) -> IResult<&str, &str> { -//! many1( -//! terminated(one_of("0123456789"), many0('_').map(|()| ())) +//! repeat(1.., +//! terminated(one_of("0123456789"), repeat(0.., '_').map(|()| ())) //! ). //! map(|()| ()) //! .recognize() diff --git a/vendor/winnow/src/_topic/mod.rs b/vendor/winnow/src/_topic/mod.rs index 76687277a..72c8145fe 100644 --- a/vendor/winnow/src/_topic/mod.rs +++ b/vendor/winnow/src/_topic/mod.rs @@ -12,6 +12,7 @@ //! - [HTTP][http] //! - Special Topics: //! - [Implementing `FromStr`][fromstr] +//! - [Performance][performance] //! - [Parsing Partial Input][partial] //! - [Custom stream][stream] //! - [Custom errors][error] @@ -19,6 +20,7 @@ //! See also parsers written with `winnow`: //! //! - [`toml_edit`](https://crates.io/crates/toml_edit) +//! - [`hcl-edit`](https://crates.io/crates/hcl-edit) pub mod arithmetic; pub mod error; @@ -28,6 +30,7 @@ pub mod ini; pub mod json; pub mod language; pub mod partial; +pub mod performance; pub mod s_expression; pub mod stream; pub mod why; diff --git a/vendor/winnow/src/_topic/partial.rs b/vendor/winnow/src/_topic/partial.rs index 263d7f127..19895d35a 100644 --- a/vendor/winnow/src/_topic/partial.rs +++ b/vendor/winnow/src/_topic/partial.rs @@ -21,7 +21,7 @@ //! Caveats: //! - `winnow` takes the approach of re-parsing from scratch. Chunks should be relatively small to //! prevent the re-parsing overhead from dominating. -//! - Parsers like [`many0`] do not know when an `eof` is from insufficient data or the end of the +//! - Parsers like [`repeat`] do not know when an `eof` is from insufficient data or the end of the //! stream, causing them to always report [`Incomplete`]. //! //! # Example @@ -38,9 +38,9 @@ #![allow(unused_imports)] // Used for intra-doc links +use crate::binary::length_value; +use crate::combinator::repeat; use crate::error::ErrMode::Incomplete; use crate::error::Needed; -use crate::multi::length_value; -use crate::multi::many0; use crate::stream::Partial; use crate::stream::StreamIsPartial; diff --git a/vendor/winnow/src/_topic/performance.rs b/vendor/winnow/src/_topic/performance.rs new file mode 100644 index 000000000..fac12da4c --- /dev/null +++ b/vendor/winnow/src/_topic/performance.rs @@ -0,0 +1,54 @@ +//! # Performance +//! +//! ## Runtime Performance +//! +//! See also the general Rust [Performance Book](https://nnethercote.github.io/perf-book/) +//! +//! Tips +//! - When enough cases of an [`alt`] have unique prefixes, prefer [`dispatch`] +//! - When parsing text, try to parse is as bytes (`u8`) rather than `char`s ([`BStr`] can make +//! debugging easier) +//! - Find simplified subsets of the grammar to parse, falling back to the full grammar when it +//! doesn't work. For example, when parsing json strings, parse them without support for escapes, +//! falling back to escape support if it fails. +//! - Watch for large return types. A surprising place these can show up is when chaining parsers +//! with a tuple. +//! +//! ## Built-time Performance +//! +//! Returning complex types as `impl Trait` can negatively impact build times. This can hit in +//! surprising cases like: +//! ```rust +//! # use winnow::prelude::*; +//! fn foo<I, O, E>() -> impl Parser<I, O, E> +//! # where +//! # I: winnow::stream::Stream<Token=O>, +//! # I: winnow::stream::StreamIsPartial, +//! # E: winnow::error::ParseError<I>, +//! { +//! // ...some chained combinators... +//! # winnow::token::any +//! } +//! ``` +//! +//! Instead, wrap the combinators in a closure to simplify the type: +//! ```rust +//! # use winnow::prelude::*; +//! fn foo<I, O, E>() -> impl Parser<I, O, E> +//! # where +//! # I: winnow::stream::Stream<Token=O>, +//! # I: winnow::stream::StreamIsPartial, +//! # E: winnow::error::ParseError<I>, +//! { +//! move |input: I| { +//! // ...some chained combinators... +//! # winnow::token::any +//! .parse_next(input) +//! } +//! } +//! ``` + +#![allow(unused_imports)] +use crate::combinator::alt; +use crate::combinator::dispatch; +use crate::stream::BStr; diff --git a/vendor/winnow/src/_topic/stream.rs b/vendor/winnow/src/_topic/stream.rs index 92841eda2..7455e185b 100644 --- a/vendor/winnow/src/_topic/stream.rs +++ b/vendor/winnow/src/_topic/stream.rs @@ -17,7 +17,7 @@ //! //! ```rust //! # use winnow::prelude::*; -//! # use winnow::bytes::tag; +//! # use winnow::token::tag; //! # type MyStream<'i> = &'i str; //! # type Output<'i> = &'i str; //! fn parser(i: MyStream<'_>) -> IResult<MyStream<'_>, Output<'_>> { diff --git a/vendor/winnow/src/_tutorial/chapter_2.rs b/vendor/winnow/src/_tutorial/chapter_2.rs index a7f9ea9e7..49b61f3f4 100644 --- a/vendor/winnow/src/_tutorial/chapter_2.rs +++ b/vendor/winnow/src/_tutorial/chapter_2.rs @@ -61,7 +61,7 @@ //! ```rust //! # use winnow::Parser; //! # use winnow::IResult; -//! use winnow::bytes::one_of; +//! use winnow::token::one_of; //! //! fn parse_digits(input: &str) -> IResult<&str, char> { //! one_of("0123456789abcdefgABCDEFG").parse_next(input) @@ -87,7 +87,7 @@ //! > list: &'static str //! > ) -> impl Parser<&'i str, char, Error<&'i str>> { //! > // ... -//! > # winnow::bytes::one_of(list) +//! > # winnow::token::one_of(list) //! > } //! > ``` //! > If you have not programmed in a language where functions are values, the type signature of the @@ -97,18 +97,18 @@ //! > configurable or stateful parsers. //! //! Some of character classes are common enough that a named parser is provided, like with: -//! - [`line_ending`][crate::character::line_ending]: Recognizes an end of line (both `\n` and `\r\n`) -//! - [`newline`][crate::character::newline]: Matches a newline character `\n` -//! - [`tab`][crate::character::tab]: Matches a tab character `\t` +//! - [`line_ending`][crate::ascii::line_ending]: Recognizes an end of line (both `\n` and `\r\n`) +//! - [`newline`][crate::ascii::newline]: Matches a newline character `\n` +//! - [`tab`][crate::ascii::tab]: Matches a tab character `\t` //! -//! You can then capture sequences of these characters with parsers like [`take_while1`]. +//! You can then capture sequences of these characters with parsers like [`take_while`]. //! ```rust //! # use winnow::Parser; //! # use winnow::IResult; -//! use winnow::bytes::take_while1; +//! use winnow::token::take_while; //! //! fn parse_digits(input: &str) -> IResult<&str, &str> { -//! take_while1("0123456789abcdefgABCDEFG").parse_next(input) +//! take_while(1.., "0123456789abcdefgABCDEFG").parse_next(input) //! } //! //! fn main() { @@ -126,7 +126,7 @@ //! ```rust //! # use winnow::Parser; //! # use winnow::IResult; -//! use winnow::character::hex_digit1; +//! use winnow::ascii::hex_digit1; //! //! fn parse_digits(input: &str) -> IResult<&str, &str> { //! hex_digit1.parse_next(input) @@ -144,11 +144,11 @@ //! ``` #![allow(unused_imports)] -use crate::bytes::one_of; -use crate::bytes::tag; -use crate::bytes::take_while1; -use crate::character::hex_digit1; +use crate::ascii::hex_digit1; use crate::stream::ContainsToken; +use crate::token::one_of; +use crate::token::tag; +use crate::token::take_while; use crate::Parser; use std::ops::RangeInclusive; diff --git a/vendor/winnow/src/_tutorial/chapter_3.rs b/vendor/winnow/src/_tutorial/chapter_3.rs index 29c5db457..8d307e324 100644 --- a/vendor/winnow/src/_tutorial/chapter_3.rs +++ b/vendor/winnow/src/_tutorial/chapter_3.rs @@ -10,7 +10,7 @@ //! Now that we can create more interesting parsers, we can sequence them together, like: //! //! ```rust -//! # use winnow::bytes::take_while1; +//! # use winnow::token::take_while; //! # use winnow::Parser; //! # use winnow::IResult; //! # @@ -19,7 +19,7 @@ //! } //! //! fn parse_digits(input: &str) -> IResult<&str, &str> { -//! take_while1(( +//! take_while(1.., ( //! ('0'..='9'), //! ('A'..='F'), //! ('a'..='f'), @@ -40,7 +40,7 @@ //! //! To sequence these together, you can just put them in a tuple: //! ```rust -//! # use winnow::bytes::take_while1; +//! # use winnow::token::take_while; //! # use winnow::Parser; //! # use winnow::IResult; //! # @@ -49,7 +49,7 @@ //! # } //! # //! # fn parse_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -75,17 +75,17 @@ //! Frequently, you won't care about the tag and you can instead use one of the provided combinators, //! like [`preceded`]: //! ```rust -//! # use winnow::bytes::take_while1; +//! # use winnow::token::take_while; //! # use winnow::Parser; //! # use winnow::IResult; -//! use winnow::sequence::preceded; +//! use winnow::combinator::preceded; //! //! # fn parse_prefix(input: &str) -> IResult<&str, &str> { //! # "0x".parse_next(input) //! # } //! # //! # fn parse_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -120,8 +120,8 @@ //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! use winnow::branch::alt; +//! # use winnow::token::take_while; +//! use winnow::combinator::alt; //! //! fn parse_digits(input: &str) -> IResult<&str, (&str, &str)> { //! alt(( @@ -134,25 +134,25 @@ //! //! // ... //! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -174,14 +174,14 @@ //! //! 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::branch::dispatch] macro: +//! [`dispatch`][crate::combinator::dispatch] macro: //! //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! use winnow::branch::dispatch; -//! use winnow::bytes::take; +//! # 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> { @@ -196,25 +196,25 @@ //! //! // ... //! # fn parse_bin_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -234,9 +234,9 @@ //! ``` #![allow(unused_imports)] -use crate::branch::alt; -use crate::branch::dispatch; -use crate::sequence::preceded; +use crate::combinator::alt; +use crate::combinator::dispatch; +use crate::combinator::preceded; 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 5d19a05bc..315d185ba 100644 --- a/vendor/winnow/src/_tutorial/chapter_4.rs +++ b/vendor/winnow/src/_tutorial/chapter_4.rs @@ -22,7 +22,7 @@ //! ```rust //! # use winnow::Parser; //! # use winnow::IResult; -//! # use winnow::character::digit1; +//! # use winnow::ascii::digit1; //! # //! fn parse_digits(input: &str) -> IResult<&str, usize> { //! digit1 @@ -41,47 +41,47 @@ //! } //! ``` //! -//! `Parser::parse_to` is just a convenient form of [`Parser::map_res`] which we can use to handle +//! `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::bytes::take_while1; -//! use winnow::branch::dispatch; -//! use winnow::bytes::take; +//! # 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> { //! dispatch!(take(2usize); -//! "0b" => parse_bin_digits.map_res(|s| usize::from_str_radix(s, 2)), -//! "0o" => parse_oct_digits.map_res(|s| usize::from_str_radix(s, 8)), -//! "0d" => parse_dec_digits.map_res(|s| usize::from_str_radix(s, 10)), -//! "0x" => parse_hex_digits.map_res(|s| usize::from_str_radix(s, 16)), +//! "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> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), diff --git a/vendor/winnow/src/_tutorial/chapter_5.rs b/vendor/winnow/src/_tutorial/chapter_5.rs index b703bcf5c..3a4be4b32 100644 --- a/vendor/winnow/src/_tutorial/chapter_5.rs +++ b/vendor/winnow/src/_tutorial/chapter_5.rs @@ -1,55 +1,55 @@ //! # 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 many times into a [`Vec`]. +//! single parser multiple times, collecting the result into a [`Vec`]. //! -//! Let's take our `parse_digits` and collect a list of them with [`many0`]: +//! Let's take our `parse_digits` and collect a list of them with [`repeat`]: //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! # use winnow::branch::dispatch; -//! # use winnow::bytes::take; +//! # use winnow::token::take_while; +//! # use winnow::combinator::dispatch; +//! # use winnow::token::take; //! # use winnow::combinator::fail; //! use winnow::combinator::opt; -//! use winnow::multi::many0; -//! use winnow::sequence::terminated; +//! use winnow::combinator::repeat; +//! use winnow::combinator::terminated; //! //! fn parse_list(input: &str) -> IResult<&str, Vec<usize>> { -//! many0(terminated(parse_digits, opt(','))).parse_next(input) +//! repeat(0.., terminated(parse_digits, opt(','))).parse_next(input) //! } //! //! // ... //! # fn parse_digits(input: &str) -> IResult<&str, usize> { //! # dispatch!(take(2usize); -//! # "0b" => parse_bin_digits.map_res(|s| usize::from_str_radix(s, 2)), -//! # "0o" => parse_oct_digits.map_res(|s| usize::from_str_radix(s, 8)), -//! # "0d" => parse_dec_digits.map_res(|s| usize::from_str_radix(s, 10)), -//! # "0x" => parse_hex_digits.map_res(|s| usize::from_str_radix(s, 16)), +//! # "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> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -73,11 +73,11 @@ //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! # use winnow::branch::dispatch; -//! # use winnow::bytes::take; +//! # use winnow::token::take_while; +//! # use winnow::combinator::dispatch; +//! # use winnow::token::take; //! # use winnow::combinator::fail; -//! use winnow::multi::separated0; +//! use winnow::combinator::separated0; //! //! fn parse_list(input: &str) -> IResult<&str, Vec<usize>> { //! separated0(parse_digits, ",").parse_next(input) @@ -86,34 +86,34 @@ //! // ... //! # fn parse_digits(input: &str) -> IResult<&str, usize> { //! # dispatch!(take(2usize); -//! # "0b" => parse_bin_digits.map_res(|s| usize::from_str_radix(s, 2)), -//! # "0o" => parse_oct_digits.map_res(|s| usize::from_str_radix(s, 8)), -//! # "0d" => parse_dec_digits.map_res(|s| usize::from_str_radix(s, 10)), -//! # "0x" => parse_hex_digits.map_res(|s| usize::from_str_radix(s, 16)), +//! # "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> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -132,17 +132,17 @@ //! } //! ``` //! -//! If you look closely at [`many0`], it isn't collecting directly into a [`Vec`] but +//! If you look closely at [`repeat`], it isn't collecting directly into a [`Vec`] but //! [`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::bytes::take_while1; -//! # use winnow::branch::dispatch; -//! # use winnow::bytes::take; +//! # use winnow::token::take_while; +//! # use winnow::combinator::dispatch; +//! # use winnow::token::take; //! # use winnow::combinator::fail; -//! # use winnow::multi::separated0; +//! # use winnow::combinator::separated0; //! # //! fn recognize_list(input: &str) -> IResult<&str, &str> { //! parse_list.recognize().parse_next(input) @@ -155,34 +155,34 @@ //! // ... //! # fn parse_digits(input: &str) -> IResult<&str, usize> { //! # dispatch!(take(2usize); -//! # "0b" => parse_bin_digits.map_res(|s| usize::from_str_radix(s, 2)), -//! # "0o" => parse_oct_digits.map_res(|s| usize::from_str_radix(s, 8)), -//! # "0d" => parse_dec_digits.map_res(|s| usize::from_str_radix(s, 10)), -//! # "0x" => parse_hex_digits.map_res(|s| usize::from_str_radix(s, 16)), +//! # "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> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -204,8 +204,8 @@ #![allow(unused_imports)] use super::chapter_2; use super::chapter_3; -use crate::multi::many0; -use crate::multi::separated0; +use crate::combinator::repeat; +use crate::combinator::separated0; use crate::stream::Accumulate; use crate::Parser; use std::vec::Vec; diff --git a/vendor/winnow/src/_tutorial/chapter_6.rs b/vendor/winnow/src/_tutorial/chapter_6.rs index 74169429d..268e38a31 100644 --- a/vendor/winnow/src/_tutorial/chapter_6.rs +++ b/vendor/winnow/src/_tutorial/chapter_6.rs @@ -14,8 +14,8 @@ //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! # use winnow::branch::alt; +//! # use winnow::token::take_while; +//! # use winnow::combinator::alt; //! use winnow::error::VerboseError; //! //! fn parse_digits(input: &str) -> IResult<&str, (&str, &str), VerboseError<&str>> { @@ -29,25 +29,25 @@ //! //! // ... //! # fn parse_bin_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -89,8 +89,8 @@ //! ```rust //! # use winnow::IResult; //! # use winnow::Parser; -//! # use winnow::bytes::take_while1; -//! # use winnow::branch::alt; +//! # use winnow::token::take_while; +//! # use winnow::combinator::alt; //! # use winnow::error::VerboseError; //! use winnow::combinator::cut_err; //! @@ -105,25 +105,25 @@ //! //! // ... //! # fn parse_bin_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str, VerboseError<&str>> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), @@ -145,7 +145,7 @@ #![allow(unused_imports)] use super::chapter_1; use super::chapter_3; -use crate::branch::alt; +use crate::combinator::alt; use crate::combinator::cut_err; use crate::error::ErrMode; use crate::error::Error; diff --git a/vendor/winnow/src/_tutorial/chapter_7.rs b/vendor/winnow/src/_tutorial/chapter_7.rs index 8c27cb5ad..c20607c36 100644 --- a/vendor/winnow/src/_tutorial/chapter_7.rs +++ b/vendor/winnow/src/_tutorial/chapter_7.rs @@ -27,9 +27,9 @@ //! winnow provides some helpers for this: //! ```rust //! # use winnow::IResult; -//! # use winnow::bytes::take_while1; -//! # use winnow::branch::dispatch; -//! # use winnow::bytes::take; +//! # use winnow::token::take_while; +//! # use winnow::combinator::dispatch; +//! # use winnow::token::take; //! # use winnow::combinator::fail; //! use winnow::Parser; //! use winnow::error::Error; @@ -51,34 +51,34 @@ //! // ... //! # fn parse_digits(input: &str) -> IResult<&str, usize> { //! # dispatch!(take(2usize); -//! # "0b" => parse_bin_digits.map_res(|s| usize::from_str_radix(s, 2)), -//! # "0o" => parse_oct_digits.map_res(|s| usize::from_str_radix(s, 8)), -//! # "0d" => parse_dec_digits.map_res(|s| usize::from_str_radix(s, 10)), -//! # "0x" => parse_hex_digits.map_res(|s| usize::from_str_radix(s, 16)), +//! # "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> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_oct_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='7'), //! # )).parse_next(input) //! # } //! # //! # fn parse_dec_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # )).parse_next(input) //! # } //! # //! # fn parse_hex_digits(input: &str) -> IResult<&str, &str> { -//! # take_while1(( +//! # take_while(1.., ( //! # ('0'..='9'), //! # ('A'..='F'), //! # ('a'..='f'), diff --git a/vendor/winnow/src/character/mod.rs b/vendor/winnow/src/ascii/mod.rs index 89cc9ec09..4ada7c00b 100644 --- a/vendor/winnow/src/character/mod.rs +++ b/vendor/winnow/src/ascii/mod.rs @@ -7,11 +7,9 @@ mod tests; use crate::lib::std::ops::{Add, Shl}; -use crate::branch::alt; -use crate::bytes::one_of; +use crate::combinator::alt; +use crate::token::one_of; -use crate::bytes::take_while0; -use crate::bytes::take_while1; use crate::combinator::cut_err; use crate::combinator::opt; use crate::error::ParseError; @@ -19,6 +17,7 @@ use crate::error::{ErrMode, ErrorKind, Needed}; use crate::stream::ContainsToken; use crate::stream::{AsBStr, AsChar, Offset, ParseSlice, Stream, StreamIsPartial}; use crate::stream::{Compare, CompareResult}; +use crate::token::take_while; use crate::trace::trace; use crate::IResult; use crate::Parser; @@ -33,7 +32,7 @@ use crate::Parser; /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult}; -/// # use winnow::character::crlf; +/// # use winnow::ascii::crlf; /// fn parser(input: &str) -> IResult<&str, &str> { /// crlf(input) /// } @@ -46,7 +45,7 @@ use crate::Parser; /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::crlf; +/// # use winnow::ascii::crlf; /// assert_eq!(crlf::<_, Error<_>>(Partial::new("\r\nc")), Ok((Partial::new("c"), "\r\n"))); /// assert_eq!(crlf::<_, Error<_>>(Partial::new("ab\r\nc")), Err(ErrMode::Backtrack(Error::new(Partial::new("ab\r\nc"), ErrorKind::Tag)))); /// assert_eq!(crlf::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(2)))); @@ -71,7 +70,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::not_line_ending; +/// # use winnow::ascii::not_line_ending; /// fn parser(input: &str) -> IResult<&str, &str> { /// not_line_ending(input) /// } @@ -87,7 +86,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::not_line_ending; +/// # use winnow::ascii::not_line_ending; /// assert_eq!(not_line_ending::<_, Error<_>>(Partial::new("ab\r\nc")), Ok((Partial::new("\r\nc"), "ab"))); /// assert_eq!(not_line_ending::<_, Error<_>>(Partial::new("abc")), Err(ErrMode::Incomplete(Needed::Unknown))); /// assert_eq!(not_line_ending::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::Unknown))); @@ -103,28 +102,30 @@ where <I as Stream>::Token: AsChar, { trace("not_line_ending", move |input: I| { - if input.is_partial() { - streaming_not_line_ending(input) + if <I as StreamIsPartial>::is_partial_supported() { + not_line_ending_::<_, _, true>(input) } else { - complete_not_line_ending(input) + not_line_ending_::<_, _, false>(input) } }) .parse_next(input) } -pub(crate) fn streaming_not_line_ending<T, E: ParseError<T>>( - input: T, -) -> IResult<T, <T as Stream>::Slice, E> +fn not_line_ending_<I, E: ParseError<I>, const PARTIAL: bool>( + input: I, +) -> IResult<I, <I as Stream>::Slice, E> where - T: Stream + AsBStr, - T: Compare<&'static str>, - <T as Stream>::Token: AsChar, + I: StreamIsPartial, + I: Stream + AsBStr, + I: Compare<&'static str>, + <I as Stream>::Token: AsChar, { match input.offset_for(|item| { let c = item.as_char(); c == '\r' || c == '\n' }) { - None => Err(ErrMode::Incomplete(Needed::Unknown)), + None if PARTIAL && input.is_partial() => Err(ErrMode::Incomplete(Needed::Unknown)), + None => Ok(input.next_slice(input.eof_offset())), Some(offset) => { let (new_input, res) = input.next_slice(offset); let bytes = new_input.as_bstr(); @@ -134,42 +135,9 @@ where match comp { //FIXME: calculate the right index CompareResult::Ok => {} - CompareResult::Incomplete => { + CompareResult::Incomplete if PARTIAL && input.is_partial() => { return Err(ErrMode::Incomplete(Needed::Unknown)); } - CompareResult::Error => { - let e: ErrorKind = ErrorKind::Tag; - return Err(ErrMode::from_error_kind(input, e)); - } - } - } - Ok((new_input, res)) - } - } -} - -pub(crate) fn complete_not_line_ending<T, E: ParseError<T>>( - input: T, -) -> IResult<T, <T as Stream>::Slice, E> -where - T: Stream + AsBStr, - T: Compare<&'static str>, - <T as Stream>::Token: AsChar, -{ - match input.offset_for(|item| { - let c = item.as_char(); - c == '\r' || c == '\n' - }) { - None => Ok(input.next_slice(input.eof_offset())), - Some(offset) => { - let (new_input, res) = input.next_slice(offset); - let bytes = new_input.as_bstr(); - let nth = bytes[0]; - if nth == b'\r' { - let comp = new_input.compare("\r\n"); - match comp { - //FIXME: calculate the right index - CompareResult::Ok => {} CompareResult::Incomplete | CompareResult::Error => { let e: ErrorKind = ErrorKind::Tag; return Err(ErrMode::from_error_kind(input, e)); @@ -191,7 +159,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::line_ending; +/// # use winnow::ascii::line_ending; /// fn parser(input: &str) -> IResult<&str, &str> { /// line_ending(input) /// } @@ -204,7 +172,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::line_ending; +/// # use winnow::ascii::line_ending; /// assert_eq!(line_ending::<_, Error<_>>(Partial::new("\r\nc")), Ok((Partial::new("c"), "\r\n"))); /// assert_eq!(line_ending::<_, Error<_>>(Partial::new("ab\r\nc")), Err(ErrMode::Backtrack(Error::new(Partial::new("ab\r\nc"), ErrorKind::Tag)))); /// assert_eq!(line_ending::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -232,7 +200,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::newline; +/// # use winnow::ascii::newline; /// fn parser(input: &str) -> IResult<&str, char> { /// newline(input) /// } @@ -245,7 +213,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::newline; +/// # use winnow::ascii::newline; /// assert_eq!(newline::<_, Error<_>>(Partial::new("\nc")), Ok((Partial::new("c"), '\n'))); /// assert_eq!(newline::<_, Error<_>>(Partial::new("\r\nc")), Err(ErrMode::Backtrack(Error::new(Partial::new("\r\nc"), ErrorKind::Verify)))); /// assert_eq!(newline::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -274,7 +242,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::tab; +/// # use winnow::ascii::tab; /// fn parser(input: &str) -> IResult<&str, char> { /// tab(input) /// } @@ -287,7 +255,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::tab; +/// # use winnow::ascii::tab; /// assert_eq!(tab::<_, Error<_>>(Partial::new("\tc")), Ok((Partial::new("c"), '\t'))); /// assert_eq!(tab::<_, Error<_>>(Partial::new("\r\nc")), Err(ErrMode::Backtrack(Error::new(Partial::new("\r\nc"), ErrorKind::Verify)))); /// assert_eq!(tab::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -318,7 +286,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::alpha0; +/// # use winnow::ascii::alpha0; /// fn parser(input: &str) -> IResult<&str, &str> { /// alpha0(input) /// } @@ -331,7 +299,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::alpha0; +/// # use winnow::ascii::alpha0; /// assert_eq!(alpha0::<_, Error<_>>(Partial::new("ab1c")), Ok((Partial::new("1c"), "ab"))); /// assert_eq!(alpha0::<_, Error<_>>(Partial::new("1c")), Ok((Partial::new("1c"), ""))); /// assert_eq!(alpha0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -344,7 +312,7 @@ where <I as Stream>::Token: AsChar, { trace("alpha0", move |input: I| { - take_while0(|c: <I as Stream>::Token| c.is_alpha()).parse_next(input) + take_while(0.., |c: <I as Stream>::Token| c.is_alpha()).parse_next(input) }) .parse_next(input) } @@ -361,7 +329,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::alpha1; +/// # use winnow::ascii::alpha1; /// fn parser(input: &str) -> IResult<&str, &str> { /// alpha1(input) /// } @@ -374,7 +342,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::alpha1; +/// # use winnow::ascii::alpha1; /// assert_eq!(alpha1::<_, Error<_>>(Partial::new("aB1c")), Ok((Partial::new("1c"), "aB"))); /// assert_eq!(alpha1::<_, Error<_>>(Partial::new("1c")), Err(ErrMode::Backtrack(Error::new(Partial::new("1c"), ErrorKind::Slice)))); /// assert_eq!(alpha1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -387,7 +355,7 @@ where <I as Stream>::Token: AsChar, { trace("alpha1", move |input: I| { - take_while1(|c: <I as Stream>::Token| c.is_alpha()).parse_next(input) + take_while(1.., |c: <I as Stream>::Token| c.is_alpha()).parse_next(input) }) .parse_next(input) } @@ -404,7 +372,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::digit0; +/// # use winnow::ascii::digit0; /// fn parser(input: &str) -> IResult<&str, &str> { /// digit0(input) /// } @@ -418,7 +386,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::digit0; +/// # use winnow::ascii::digit0; /// assert_eq!(digit0::<_, Error<_>>(Partial::new("21c")), Ok((Partial::new("c"), "21"))); /// assert_eq!(digit0::<_, Error<_>>(Partial::new("a21c")), Ok((Partial::new("a21c"), ""))); /// assert_eq!(digit0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -431,7 +399,7 @@ where <I as Stream>::Token: AsChar, { trace("digit0", move |input: I| { - take_while0(|c: <I as Stream>::Token| c.is_dec_digit()).parse_next(input) + take_while(0.., |c: <I as Stream>::Token| c.is_dec_digit()).parse_next(input) }) .parse_next(input) } @@ -448,7 +416,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::digit1; +/// # use winnow::ascii::digit1; /// fn parser(input: &str) -> IResult<&str, &str> { /// digit1(input) /// } @@ -461,7 +429,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::digit1; +/// # use winnow::ascii::digit1; /// assert_eq!(digit1::<_, Error<_>>(Partial::new("21c")), Ok((Partial::new("c"), "21"))); /// assert_eq!(digit1::<_, Error<_>>(Partial::new("c1")), Err(ErrMode::Backtrack(Error::new(Partial::new("c1"), ErrorKind::Slice)))); /// assert_eq!(digit1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -469,13 +437,13 @@ where /// /// ## Parsing an integer /// -/// You can use `digit1` in combination with [`Parser::map_res`][crate::Parser::map_res] to parse an integer: +/// You can use `digit1` in combination with [`Parser::try_map`][crate::Parser::try_map] to parse an integer: /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed, Parser}; -/// # use winnow::character::digit1; +/// # use winnow::ascii::digit1; /// fn parser(input: &str) -> IResult<&str, u32> { -/// digit1.map_res(str::parse).parse_next(input) +/// digit1.try_map(str::parse).parse_next(input) /// } /// /// assert_eq!(parser("416"), Ok(("", 416))); @@ -490,7 +458,7 @@ where <I as Stream>::Token: AsChar, { trace("digit1", move |input: I| { - take_while1(|c: <I as Stream>::Token| c.is_dec_digit()).parse_next(input) + take_while(1.., |c: <I as Stream>::Token| c.is_dec_digit()).parse_next(input) }) .parse_next(input) } @@ -506,7 +474,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::hex_digit0; +/// # use winnow::ascii::hex_digit0; /// fn parser(input: &str) -> IResult<&str, &str> { /// hex_digit0(input) /// } @@ -519,7 +487,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::hex_digit0; +/// # use winnow::ascii::hex_digit0; /// assert_eq!(hex_digit0::<_, Error<_>>(Partial::new("21cZ")), Ok((Partial::new("Z"), "21c"))); /// assert_eq!(hex_digit0::<_, Error<_>>(Partial::new("Z21c")), Ok((Partial::new("Z21c"), ""))); /// assert_eq!(hex_digit0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -532,7 +500,7 @@ where <I as Stream>::Token: AsChar, { trace("hex_digit0", move |input: I| { - take_while0(|c: <I as Stream>::Token| c.is_hex_digit()).parse_next(input) + take_while(0.., |c: <I as Stream>::Token| c.is_hex_digit()).parse_next(input) }) .parse_next(input) } @@ -549,7 +517,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::hex_digit1; +/// # use winnow::ascii::hex_digit1; /// fn parser(input: &str) -> IResult<&str, &str> { /// hex_digit1(input) /// } @@ -562,7 +530,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::hex_digit1; +/// # use winnow::ascii::hex_digit1; /// assert_eq!(hex_digit1::<_, Error<_>>(Partial::new("21cZ")), Ok((Partial::new("Z"), "21c"))); /// assert_eq!(hex_digit1::<_, Error<_>>(Partial::new("H2")), Err(ErrMode::Backtrack(Error::new(Partial::new("H2"), ErrorKind::Slice)))); /// assert_eq!(hex_digit1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -575,7 +543,7 @@ where <I as Stream>::Token: AsChar, { trace("hex_digit1", move |input: I| { - take_while1(|c: <I as Stream>::Token| c.is_hex_digit()).parse_next(input) + take_while(1.., |c: <I as Stream>::Token| c.is_hex_digit()).parse_next(input) }) .parse_next(input) } @@ -592,7 +560,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::oct_digit0; +/// # use winnow::ascii::oct_digit0; /// fn parser(input: &str) -> IResult<&str, &str> { /// oct_digit0(input) /// } @@ -605,7 +573,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::oct_digit0; +/// # use winnow::ascii::oct_digit0; /// assert_eq!(oct_digit0::<_, Error<_>>(Partial::new("21cZ")), Ok((Partial::new("cZ"), "21"))); /// assert_eq!(oct_digit0::<_, Error<_>>(Partial::new("Z21c")), Ok((Partial::new("Z21c"), ""))); /// assert_eq!(oct_digit0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -618,7 +586,7 @@ where <I as Stream>::Token: AsChar, { trace("oct_digit0", move |input: I| { - take_while0(|c: <I as Stream>::Token| c.is_oct_digit()).parse_next(input) + take_while(0.., |c: <I as Stream>::Token| c.is_oct_digit()).parse_next(input) }) .parse_next(input) } @@ -635,7 +603,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::oct_digit1; +/// # use winnow::ascii::oct_digit1; /// fn parser(input: &str) -> IResult<&str, &str> { /// oct_digit1(input) /// } @@ -648,7 +616,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::oct_digit1; +/// # use winnow::ascii::oct_digit1; /// assert_eq!(oct_digit1::<_, Error<_>>(Partial::new("21cZ")), Ok((Partial::new("cZ"), "21"))); /// assert_eq!(oct_digit1::<_, Error<_>>(Partial::new("H2")), Err(ErrMode::Backtrack(Error::new(Partial::new("H2"), ErrorKind::Slice)))); /// assert_eq!(oct_digit1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -661,7 +629,7 @@ where <I as Stream>::Token: AsChar, { trace("oct_digit0", move |input: I| { - take_while1(|c: <I as Stream>::Token| c.is_oct_digit()).parse_next(input) + take_while(1.., |c: <I as Stream>::Token| c.is_oct_digit()).parse_next(input) }) .parse_next(input) } @@ -678,7 +646,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::alphanumeric0; +/// # use winnow::ascii::alphanumeric0; /// fn parser(input: &str) -> IResult<&str, &str> { /// alphanumeric0(input) /// } @@ -691,7 +659,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::alphanumeric0; +/// # use winnow::ascii::alphanumeric0; /// assert_eq!(alphanumeric0::<_, Error<_>>(Partial::new("21cZ%1")), Ok((Partial::new("%1"), "21cZ"))); /// assert_eq!(alphanumeric0::<_, Error<_>>(Partial::new("&Z21c")), Ok((Partial::new("&Z21c"), ""))); /// assert_eq!(alphanumeric0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -704,7 +672,7 @@ where <I as Stream>::Token: AsChar, { trace("alphanumeric0", move |input: I| { - take_while0(|c: <I as Stream>::Token| c.is_alphanum()).parse_next(input) + take_while(0.., |c: <I as Stream>::Token| c.is_alphanum()).parse_next(input) }) .parse_next(input) } @@ -721,7 +689,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::alphanumeric1; +/// # use winnow::ascii::alphanumeric1; /// fn parser(input: &str) -> IResult<&str, &str> { /// alphanumeric1(input) /// } @@ -734,7 +702,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::alphanumeric1; +/// # use winnow::ascii::alphanumeric1; /// assert_eq!(alphanumeric1::<_, Error<_>>(Partial::new("21cZ%1")), Ok((Partial::new("%1"), "21cZ"))); /// assert_eq!(alphanumeric1::<_, Error<_>>(Partial::new("&H2")), Err(ErrMode::Backtrack(Error::new(Partial::new("&H2"), ErrorKind::Slice)))); /// assert_eq!(alphanumeric1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -747,7 +715,7 @@ where <I as Stream>::Token: AsChar, { trace("alphanumeric1", move |input: I| { - take_while1(|c: <I as Stream>::Token| c.is_alphanum()).parse_next(input) + take_while(1.., |c: <I as Stream>::Token| c.is_alphanum()).parse_next(input) }) .parse_next(input) } @@ -765,7 +733,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::space0; +/// # use winnow::ascii::space0; /// assert_eq!(space0::<_, Error<_>>(Partial::new(" \t21c")), Ok((Partial::new("21c"), " \t"))); /// assert_eq!(space0::<_, Error<_>>(Partial::new("Z21c")), Ok((Partial::new("Z21c"), ""))); /// assert_eq!(space0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -778,7 +746,7 @@ where <I as Stream>::Token: AsChar + Copy, { trace("space0", move |input: I| { - take_while0(|c: <I as Stream>::Token| { + take_while(0.., |c: <I as Stream>::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') }) @@ -799,7 +767,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::space1; +/// # use winnow::ascii::space1; /// fn parser(input: &str) -> IResult<&str, &str> { /// space1(input) /// } @@ -812,7 +780,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::space1; +/// # use winnow::ascii::space1; /// assert_eq!(space1::<_, Error<_>>(Partial::new(" \t21c")), Ok((Partial::new("21c"), " \t"))); /// assert_eq!(space1::<_, Error<_>>(Partial::new("H2")), Err(ErrMode::Backtrack(Error::new(Partial::new("H2"), ErrorKind::Slice)))); /// assert_eq!(space1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -825,7 +793,7 @@ where <I as Stream>::Token: AsChar + Copy, { trace("space1", move |input: I| { - take_while1(|c: <I as Stream>::Token| { + take_while(1.., |c: <I as Stream>::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t') }) @@ -846,7 +814,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; -/// # use winnow::character::multispace0; +/// # use winnow::ascii::multispace0; /// fn parser(input: &str) -> IResult<&str, &str> { /// multispace0(input) /// } @@ -859,7 +827,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::multispace0; +/// # use winnow::ascii::multispace0; /// assert_eq!(multispace0::<_, Error<_>>(Partial::new(" \t\n\r21c")), Ok((Partial::new("21c"), " \t\n\r"))); /// assert_eq!(multispace0::<_, Error<_>>(Partial::new("Z21c")), Ok((Partial::new("Z21c"), ""))); /// assert_eq!(multispace0::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -872,7 +840,7 @@ where <I as Stream>::Token: AsChar + Copy, { trace("multispace0", move |input: I| { - take_while0(|c: <I as Stream>::Token| { + take_while(0.., |c: <I as Stream>::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') }) @@ -893,7 +861,7 @@ where /// /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult, error::Needed}; -/// # use winnow::character::multispace1; +/// # use winnow::ascii::multispace1; /// fn parser(input: &str) -> IResult<&str, &str> { /// multispace1(input) /// } @@ -906,7 +874,7 @@ where /// ``` /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, error::Needed}; /// # use winnow::Partial; -/// # use winnow::character::multispace1; +/// # use winnow::ascii::multispace1; /// assert_eq!(multispace1::<_, Error<_>>(Partial::new(" \t\n\r21c")), Ok((Partial::new("21c"), " \t\n\r"))); /// assert_eq!(multispace1::<_, Error<_>>(Partial::new("H2")), Err(ErrMode::Backtrack(Error::new(Partial::new("H2"), ErrorKind::Slice)))); /// assert_eq!(multispace1::<_, Error<_>>(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -919,7 +887,7 @@ where <I as Stream>::Token: AsChar + Copy, { trace("multispace1", move |input: I| { - take_while1(|c: <I as Stream>::Token| { + take_while(1.., |c: <I as Stream>::Token| { let ch = c.as_char(); matches!(ch, ' ' | '\t' | '\r' | '\n') }) @@ -947,7 +915,7 @@ where { trace("dec_uint", move |input: I| { if input.eof_offset() == 0 { - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { return Err(ErrMode::Incomplete(Needed::new(1))); } else { return Err(ErrMode::from_error_kind(input, ErrorKind::Slice)); @@ -974,7 +942,7 @@ where } } - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { Err(ErrMode::Incomplete(Needed::new(1))) } else { Ok((input.next_slice(input.eof_offset()).0, value)) @@ -1103,12 +1071,12 @@ where let token = token.as_char(); token == '+' || token == '-' } - let (input, sign) = opt(crate::bytes::one_of(sign).map(AsChar::as_char)) + let (input, sign) = opt(crate::token::one_of(sign).map(AsChar::as_char)) .map(|c| c != Some('-')) .parse_next(input)?; if input.eof_offset() == 0 { - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { return Err(ErrMode::Incomplete(Needed::new(1))); } else { return Err(ErrMode::from_error_kind(input, ErrorKind::Slice)); @@ -1139,7 +1107,7 @@ where } } - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { Err(ErrMode::Incomplete(Needed::new(1))) } else { Ok((input.next_slice(input.eof_offset()).0, value)) @@ -1197,7 +1165,7 @@ impl Int for i128 { /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// use winnow::character::hex_uint; +/// use winnow::ascii::hex_uint; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u32> { /// hex_uint(s) @@ -1212,7 +1180,7 @@ impl Int for i128 { /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::Partial; -/// use winnow::character::hex_uint; +/// use winnow::ascii::hex_uint; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { /// hex_uint(s) @@ -1250,7 +1218,10 @@ where } } Err(_) => { - if input.is_partial() && invalid_offset == input.eof_offset() { + if <I as StreamIsPartial>::is_partial_supported() + && input.is_partial() + && invalid_offset == input.eof_offset() + { // Only the next byte is guaranteed required return Err(ErrMode::Incomplete(Needed::new(1))); } else { @@ -1332,7 +1303,7 @@ impl HexUint for u128 { /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; -/// use winnow::character::float; +/// use winnow::ascii::float; /// /// fn parser(s: &str) -> IResult<&str, f64> { /// float(s) @@ -1349,7 +1320,7 @@ impl HexUint for u128 { /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::character::float; +/// use winnow::ascii::float; /// /// fn parser(s: Partial<&str>) -> IResult<Partial<&str>, f64> { /// float(s) @@ -1399,9 +1370,9 @@ where { alt(( recognize_float, - crate::bytes::tag_no_case("nan"), - crate::bytes::tag_no_case("inf"), - crate::bytes::tag_no_case("infinity"), + crate::token::tag_no_case("nan"), + crate::token::tag_no_case("inf"), + crate::token::tag_no_case("infinity"), )) .parse_next(input) } @@ -1438,10 +1409,10 @@ where /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed, IResult}; -/// # use winnow::character::digit1; +/// # use winnow::ascii::digit1; /// # use winnow::prelude::*; -/// use winnow::character::escaped; -/// use winnow::bytes::one_of; +/// use winnow::ascii::escaped; +/// use winnow::token::one_of; /// /// fn esc(s: &str) -> IResult<&str, &str> { /// escaped(digit1, '\\', one_of(r#""n\"#)).parse_next(s) @@ -1453,11 +1424,11 @@ where /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed, IResult}; -/// # use winnow::character::digit1; +/// # use winnow::ascii::digit1; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::character::escaped; -/// use winnow::bytes::one_of; +/// use winnow::ascii::escaped; +/// use winnow::token::one_of; /// /// fn esc(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// escaped(digit1, '\\', one_of("\"n\\")).parse_next(s) @@ -1481,7 +1452,7 @@ where Error: ParseError<I>, { trace("escaped", move |input: I| { - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { streaming_escaped_internal(input, &mut normal, control_char, &mut escapable) } else { complete_escaped_internal(input, &mut normal, control_char, &mut escapable) @@ -1489,13 +1460,14 @@ where }) } -pub(crate) fn streaming_escaped_internal<I, Error, F, G, O1, O2>( +fn streaming_escaped_internal<I, Error, F, G, O1, O2>( input: I, normal: &mut F, control_char: char, escapable: &mut G, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + Offset, <I as Stream>::Token: crate::stream::AsChar, F: Parser<I, O1, Error>, @@ -1545,13 +1517,14 @@ where Err(ErrMode::Incomplete(Needed::Unknown)) } -pub(crate) fn complete_escaped_internal<'a, I: 'a, Error, F, G, O1, O2>( +fn complete_escaped_internal<'a, I: 'a, Error, F, G, O1, O2>( input: I, normal: &mut F, control_char: char, escapable: &mut G, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + Offset, <I as Stream>::Token: crate::stream::AsChar, F: Parser<I, O1, Error>, @@ -1617,10 +1590,10 @@ where /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use std::str::from_utf8; -/// use winnow::bytes::tag; -/// use winnow::character::escaped_transform; -/// use winnow::character::alpha1; -/// use winnow::branch::alt; +/// use winnow::token::tag; +/// use winnow::ascii::escaped_transform; +/// use winnow::ascii::alpha1; +/// use winnow::combinator::alt; /// /// fn parser(input: &str) -> IResult<&str, String> { /// escaped_transform( @@ -1643,10 +1616,10 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use std::str::from_utf8; /// # use winnow::Partial; -/// use winnow::bytes::tag; -/// use winnow::character::escaped_transform; -/// use winnow::character::alpha1; -/// use winnow::branch::alt; +/// use winnow::token::tag; +/// use winnow::ascii::escaped_transform; +/// use winnow::ascii::alpha1; +/// use winnow::combinator::alt; /// /// fn parser(input: Partial<&str>) -> IResult<Partial<&str>, String> { /// escaped_transform( @@ -1679,7 +1652,7 @@ where Error: ParseError<I>, { trace("escaped_transform", move |input: I| { - if input.is_partial() { + if <I as StreamIsPartial>::is_partial_supported() && input.is_partial() { streaming_escaped_transform_internal(input, &mut normal, control_char, &mut transform) } else { complete_escaped_transform_internal(input, &mut normal, control_char, &mut transform) @@ -1688,13 +1661,14 @@ where } #[cfg(feature = "alloc")] -pub(crate) fn streaming_escaped_transform_internal<I, Error, F, G, Output>( +fn streaming_escaped_transform_internal<I, Error, F, G, Output>( input: I, normal: &mut F, control_char: char, transform: &mut G, ) -> IResult<I, Output, Error> where + I: StreamIsPartial, I: Stream + Offset, <I as Stream>::Token: crate::stream::AsChar, Output: crate::stream::Accumulate<<I as Stream>::Slice>, @@ -1746,13 +1720,14 @@ where } #[cfg(feature = "alloc")] -pub(crate) fn complete_escaped_transform_internal<I, Error, F, G, Output>( +fn complete_escaped_transform_internal<I, Error, F, G, Output>( input: I, normal: &mut F, control_char: char, transform: &mut G, ) -> IResult<I, Output, Error> where + I: StreamIsPartial, I: Stream + Offset, <I as Stream>::Token: crate::stream::AsChar, Output: crate::stream::Accumulate<<I as Stream>::Slice>, diff --git a/vendor/winnow/src/character/tests.rs b/vendor/winnow/src/ascii/tests.rs index 95a63c303..b715d0920 100644 --- a/vendor/winnow/src/character/tests.rs +++ b/vendor/winnow/src/ascii/tests.rs @@ -2,14 +2,14 @@ use super::*; mod complete { use super::*; - use crate::branch::alt; - use crate::bytes::none_of; - use crate::bytes::one_of; + use crate::combinator::alt; use crate::combinator::opt; use crate::error::ErrMode; use crate::error::Error; use crate::error::ErrorKind; use crate::stream::ParseSlice; + use crate::token::none_of; + use crate::token::one_of; #[cfg(feature = "alloc")] use crate::{lib::std::string::String, lib::std::vec::Vec}; use proptest::prelude::*; @@ -569,8 +569,8 @@ mod complete { fn complete_escaped_hang() { // issue #1336 "escaped hangs if normal parser accepts empty" fn escaped_string(input: &str) -> IResult<&str, &str> { - use crate::bytes::one_of; - use crate::character::alpha0; + use crate::ascii::alpha0; + use crate::token::one_of; escaped(alpha0, '\\', one_of("n")).parse_next(input) } @@ -582,9 +582,9 @@ mod complete { fn complete_escaped_hang_1118() { // issue ##1118 escaped does not work with empty string fn unquote(input: &str) -> IResult<&str, &str> { - use crate::bytes::one_of; + use crate::combinator::delimited; use crate::combinator::opt; - use crate::sequence::delimited; + use crate::token::one_of; delimited( '"', @@ -601,8 +601,8 @@ mod complete { #[allow(unused_variables)] #[test] fn complete_escaping() { - use crate::bytes::one_of; - use crate::character::{alpha1 as alpha, digit1 as digit}; + use crate::ascii::{alpha1 as alpha, digit1 as digit}; + use crate::token::one_of; fn esc(i: &[u8]) -> IResult<&[u8], &[u8]> { escaped(alpha, '\\', one_of("\"n\\")).parse_next(i) @@ -637,8 +637,8 @@ mod complete { #[cfg(feature = "alloc")] #[test] fn complete_escaping_str() { - use crate::bytes::one_of; - use crate::character::{alpha1 as alpha, digit1 as digit}; + use crate::ascii::{alpha1 as alpha, digit1 as digit}; + use crate::token::one_of; fn esc(i: &str) -> IResult<&str, &str> { escaped(alpha, '\\', one_of("\"n\\")).parse_next(i) @@ -675,7 +675,7 @@ mod complete { #[test] fn test_escaped_error() { fn esc(s: &str) -> IResult<&str, &str> { - use crate::character::digit1; + use crate::ascii::digit1; escaped(digit1, '\\', one_of("\"n\\")).parse_next(s) } @@ -685,7 +685,7 @@ mod complete { #[cfg(feature = "alloc")] #[test] fn complete_escape_transform() { - use crate::character::alpha1 as alpha; + use crate::ascii::alpha1 as alpha; #[cfg(feature = "alloc")] fn to_s(i: Vec<u8>) -> String { @@ -761,7 +761,7 @@ mod complete { #[cfg(feature = "std")] #[test] fn complete_escape_transform_str() { - use crate::character::alpha1 as alpha; + use crate::ascii::alpha1 as alpha; fn esc(i: &str) -> IResult<&str, String> { escaped_transform( @@ -814,7 +814,7 @@ mod complete { #[cfg(feature = "alloc")] fn test_escaped_transform_error() { fn esc_trans(s: &str) -> IResult<&str, String> { - use crate::character::digit1; + use crate::ascii::digit1; escaped_transform(digit1, '\\', "n").parse_next(s) } diff --git a/vendor/winnow/src/bits/mod.rs b/vendor/winnow/src/binary/bits/mod.rs index 18cce6f67..5400e3308 100644 --- a/vendor/winnow/src/bits/mod.rs +++ b/vendor/winnow/src/binary/bits/mod.rs @@ -18,7 +18,7 @@ use crate::{IResult, Parser}; /// ``` /// use winnow::prelude::*; /// use winnow::Bytes; -/// use winnow::bits::{bits, take}; +/// use winnow::binary::bits::{bits, take}; /// use winnow::error::Error; /// /// type Stream<'i> = &'i Bytes; @@ -74,7 +74,7 @@ where /// ``` /// use winnow::prelude::*; /// use winnow::Bytes; -/// use winnow::bits::{bits, bytes, take}; +/// use winnow::binary::bits::{bits, bytes, take}; /// use winnow::combinator::rest; /// use winnow::error::Error; /// @@ -132,7 +132,7 @@ where /// # use winnow::prelude::*; /// # use winnow::Bytes; /// # use winnow::error::{Error, ErrorKind}; -/// use winnow::bits::take; +/// use winnow::binary::bits::take; /// /// type Stream<'i> = &'i Bytes; /// @@ -165,19 +165,20 @@ where { let count = count.to_usize(); trace("take", move |input: (I, usize)| { - if input.is_partial() { - streaming_take_internal(input, count) + if <I as StreamIsPartial>::is_partial_supported() { + take_::<_, _, _, true>(input, count) } else { - complete_take_internal(input, count) + take_::<_, _, _, false>(input, count) } }) } -pub(crate) fn streaming_take_internal<I, O, E: ParseError<(I, usize)>>( +fn take_<I, O, E: ParseError<(I, usize)>, const PARTIAL: bool>( (input, bit_offset): (I, usize), count: usize, ) -> IResult<(I, usize), O, E> where + I: StreamIsPartial, I: Stream<Token = u8> + AsBytes, O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>, { @@ -186,56 +187,14 @@ where } else { let cnt = (count + bit_offset).div(8); if input.eof_offset() * 8 < count + bit_offset { - Err(ErrMode::Incomplete(Needed::new(count))) - } else { - let mut acc: O = 0_u8.into(); - let mut offset: usize = bit_offset; - let mut remaining: usize = count; - let mut end_offset: usize = 0; - - for byte in input.as_bytes().iter().copied().take(cnt + 1) { - if remaining == 0 { - break; - } - let val: O = if offset == 0 { - byte.into() - } else { - (byte << offset >> offset).into() - }; - - if remaining < 8 - offset { - acc += val >> (8 - offset - remaining); - end_offset = remaining + offset; - break; - } else { - acc += val << (remaining - (8 - offset)); - remaining -= 8 - offset; - offset = 0; - } + if PARTIAL && input.is_partial() { + Err(ErrMode::Incomplete(Needed::new(count))) + } else { + Err(ErrMode::from_error_kind( + (input, bit_offset), + ErrorKind::Eof, + )) } - let (input, _) = input.next_slice(cnt); - Ok(((input, end_offset), acc)) - } - } -} - -pub(crate) fn complete_take_internal<I, O, E: ParseError<(I, usize)>>( - (input, bit_offset): (I, usize), - count: usize, -) -> IResult<(I, usize), O, E> -where - I: Stream<Token = u8> + AsBytes, - O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>, -{ - if count == 0 { - Ok(((input, bit_offset), 0u8.into())) - } else { - let cnt = (count + bit_offset).div(8); - if input.eof_offset() * 8 < count + bit_offset { - Err(ErrMode::from_error_kind( - (input, bit_offset), - ErrorKind::Eof, - )) } else { let mut acc: O = 0_u8.into(); let mut offset: usize = bit_offset; @@ -276,7 +235,7 @@ where /// # use winnow::prelude::*; /// # use winnow::Bytes; /// # use winnow::error::{Error, ErrorKind}; -/// use winnow::bits::tag; +/// use winnow::binary::bits::tag; /// /// type Stream<'i> = &'i Bytes; /// @@ -355,7 +314,7 @@ where /// # use winnow::prelude::*; /// # use winnow::Bytes; /// # use winnow::error::{Error, ErrorKind}; -/// use winnow::bits::bool; +/// use winnow::binary::bits::bool; /// /// type Stream<'i> = &'i Bytes; /// diff --git a/vendor/winnow/src/bits/tests.rs b/vendor/winnow/src/binary/bits/tests.rs index 61dba2c31..61dba2c31 100644 --- a/vendor/winnow/src/bits/tests.rs +++ b/vendor/winnow/src/binary/bits/tests.rs diff --git a/vendor/winnow/src/number/mod.rs b/vendor/winnow/src/binary/mod.rs index 1554ac729..80435e359 100644 --- a/vendor/winnow/src/number/mod.rs +++ b/vendor/winnow/src/binary/mod.rs @@ -2,16 +2,21 @@ #![allow(clippy::match_same_arms)] +pub mod bits; + #[cfg(test)] mod tests; -use crate::bytes::take; +use crate::combinator::repeat; use crate::error::ErrMode; use crate::error::ErrorKind; use crate::error::Needed; use crate::error::ParseError; use crate::lib::std::ops::{Add, Shl}; +use crate::stream::Accumulate; use crate::stream::{AsBytes, Stream, StreamIsPartial}; +use crate::stream::{ToUsize, UpdateSlice}; +use crate::token::take; use crate::trace::trace; use crate::IResult; use crate::Parser; @@ -39,7 +44,7 @@ pub enum Endianness { /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u8; +/// use winnow::binary::be_u8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u8> { /// be_u8.parse_next(s) @@ -53,7 +58,7 @@ pub enum Endianness { /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u8; +/// use winnow::binary::be_u8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> { /// be_u8.parse_next(s) @@ -83,7 +88,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u16; +/// use winnow::binary::be_u16; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u16> { /// be_u16.parse_next(s) @@ -97,7 +102,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u16; +/// use winnow::binary::be_u16; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> { /// be_u16.parse_next(s) @@ -128,7 +133,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u24; +/// use winnow::binary::be_u24; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u32> { /// be_u24.parse_next(s) @@ -142,7 +147,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u24; +/// use winnow::binary::be_u24; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { /// be_u24.parse_next(s) @@ -173,7 +178,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u32; +/// use winnow::binary::be_u32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u32> { /// be_u32.parse_next(s) @@ -187,7 +192,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u32; +/// use winnow::binary::be_u32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { /// be_u32.parse_next(s) @@ -218,7 +223,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u64; +/// use winnow::binary::be_u64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u64> { /// be_u64.parse_next(s) @@ -232,7 +237,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u64; +/// use winnow::binary::be_u64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u64> { /// be_u64.parse_next(s) @@ -263,7 +268,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_u128; +/// use winnow::binary::be_u128; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u128> { /// be_u128.parse_next(s) @@ -277,7 +282,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_u128; +/// use winnow::binary::be_u128; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u128> { /// be_u128.parse_next(s) @@ -335,7 +340,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i8; +/// use winnow::binary::be_i8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i8> { /// be_i8.parse_next(s) @@ -349,7 +354,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i8; +/// use winnow::binary::be_i8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> { /// be_i8.parse_next(s) @@ -379,7 +384,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i16; +/// use winnow::binary::be_i16; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i16> { /// be_i16.parse_next(s) @@ -393,7 +398,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i16; +/// use winnow::binary::be_i16; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i16> { /// be_i16.parse_next(s) @@ -427,7 +432,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i24; +/// use winnow::binary::be_i24; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i32> { /// be_i24.parse_next(s) @@ -441,7 +446,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i24; +/// use winnow::binary::be_i24; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> { /// be_i24.parse_next(s) @@ -483,7 +488,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i32; +/// use winnow::binary::be_i32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i32> { /// be_i32.parse_next(s) @@ -497,7 +502,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i32; +/// use winnow::binary::be_i32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> { /// be_i32.parse_next(s) @@ -531,7 +536,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i64; +/// use winnow::binary::be_i64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i64> { /// be_i64.parse_next(s) @@ -545,7 +550,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i64; +/// use winnow::binary::be_i64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i64> { /// be_i64.parse_next(s) @@ -579,7 +584,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_i128; +/// use winnow::binary::be_i128; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i128> { /// be_i128.parse_next(s) @@ -593,7 +598,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_i128; +/// use winnow::binary::be_i128; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i128> { /// be_i128.parse_next(s) @@ -627,7 +632,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u8; +/// use winnow::binary::le_u8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u8> { /// le_u8.parse_next(s) @@ -641,7 +646,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u8; +/// use winnow::binary::le_u8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> { /// le_u8.parse_next(s) @@ -671,7 +676,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u16; +/// use winnow::binary::le_u16; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u16> { /// le_u16.parse_next(s) @@ -685,7 +690,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u16; +/// use winnow::binary::le_u16; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> { /// le_u16::<_, Error<_>>.parse_next(s) @@ -716,7 +721,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u24; +/// use winnow::binary::le_u24; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u32> { /// le_u24.parse_next(s) @@ -730,7 +735,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u24; +/// use winnow::binary::le_u24; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { /// le_u24::<_, Error<_>>.parse_next(s) @@ -761,7 +766,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u32; +/// use winnow::binary::le_u32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u32> { /// le_u32.parse_next(s) @@ -775,7 +780,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u32; +/// use winnow::binary::le_u32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { /// le_u32::<_, Error<_>>.parse_next(s) @@ -806,7 +811,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u64; +/// use winnow::binary::le_u64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u64> { /// le_u64.parse_next(s) @@ -820,7 +825,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u64; +/// use winnow::binary::le_u64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u64> { /// le_u64::<_, Error<_>>.parse_next(s) @@ -851,7 +856,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_u128; +/// use winnow::binary::le_u128; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u128> { /// le_u128.parse_next(s) @@ -865,7 +870,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_u128; +/// use winnow::binary::le_u128; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u128> { /// le_u128::<_, Error<_>>.parse_next(s) @@ -922,7 +927,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i8; +/// use winnow::binary::le_i8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i8> { /// le_i8.parse_next(s) @@ -936,7 +941,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i8; +/// use winnow::binary::le_i8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> { /// le_i8.parse_next(s) @@ -966,7 +971,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i16; +/// use winnow::binary::le_i16; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i16> { /// le_i16.parse_next(s) @@ -980,7 +985,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i16; +/// use winnow::binary::le_i16; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i16> { /// le_i16::<_, Error<_>>.parse_next(s) @@ -1014,7 +1019,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i24; +/// use winnow::binary::le_i24; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i32> { /// le_i24.parse_next(s) @@ -1028,7 +1033,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i24; +/// use winnow::binary::le_i24; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> { /// le_i24::<_, Error<_>>.parse_next(s) @@ -1070,7 +1075,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i32; +/// use winnow::binary::le_i32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i32> { /// le_i32.parse_next(s) @@ -1084,7 +1089,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i32; +/// use winnow::binary::le_i32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> { /// le_i32::<_, Error<_>>.parse_next(s) @@ -1118,7 +1123,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i64; +/// use winnow::binary::le_i64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i64> { /// le_i64.parse_next(s) @@ -1132,7 +1137,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i64; +/// use winnow::binary::le_i64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i64> { /// le_i64::<_, Error<_>>.parse_next(s) @@ -1166,7 +1171,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_i128; +/// use winnow::binary::le_i128; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i128> { /// le_i128.parse_next(s) @@ -1180,7 +1185,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_i128; +/// use winnow::binary::le_i128; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i128> { /// le_i128::<_, Error<_>>.parse_next(s) @@ -1216,7 +1221,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u8; +/// use winnow::binary::u8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], u8> { /// u8.parse_next(s) @@ -1231,7 +1236,7 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u8; +/// use winnow::binary::u8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> { /// u8::<_, Error<_>>.parse_next(s) @@ -1247,38 +1252,33 @@ where I: Stream<Token = u8>, { trace("u8", move |input: I| { - if input.is_partial() { - streaming_u8(input) + if <I as StreamIsPartial>::is_partial_supported() { + u8_::<_, _, true>(input) } else { - complete_u8(input) + u8_::<_, _, false>(input) } }) .parse_next(input) } -#[inline] -pub(crate) fn streaming_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E> -where - I: Stream<Token = u8>, -{ - input - .next_token() - .ok_or_else(|| ErrMode::Incomplete(Needed::new(1))) -} - -pub(crate) fn complete_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E> +fn u8_<I, E: ParseError<I>, const PARTIAL: bool>(input: I) -> IResult<I, u8, E> where + I: StreamIsPartial, I: Stream<Token = u8>, { - input - .next_token() - .ok_or_else(|| ErrMode::Backtrack(E::from_error_kind(input, ErrorKind::Token))) + input.next_token().ok_or_else(|| { + if PARTIAL && input.is_partial() { + ErrMode::Incomplete(Needed::new(1)) + } else { + ErrMode::Backtrack(E::from_error_kind(input, ErrorKind::Token)) + } + }) } /// Recognizes an unsigned 2 bytes integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian u16 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian u16 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u16 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u16 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1290,17 +1290,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u16; +/// use winnow::binary::u16; /// /// let be_u16 = |s| { -/// u16(winnow::number::Endianness::Big).parse_next(s) +/// u16(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003))); /// assert_eq!(be_u16(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_u16 = |s| { -/// u16(winnow::number::Endianness::Little).parse_next(s) +/// u16(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300))); @@ -1312,24 +1312,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u16; +/// use winnow::binary::u16; /// /// let be_u16 = |s| { -/// u16::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// u16::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003))); /// assert_eq!(be_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// /// let le_u16 = |s| { -/// u16::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// u16::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300))); /// assert_eq!(le_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// ``` #[inline(always)] -pub fn u16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u16, E> +pub fn u16<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, u16, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1337,20 +1337,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_u16, - crate::number::Endianness::Little => le_u16, + Endianness::Big => be_u16, + Endianness::Little => le_u16, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_u16, + Endianness::Native => be_u16, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_u16, + Endianness::Native => le_u16, } }(input) } /// Recognizes an unsigned 3 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian u24 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian u24 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u24 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u24 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1362,17 +1362,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u24; +/// use winnow::binary::u24; /// /// let be_u24 = |s| { -/// u24(winnow::number::Endianness::Big).parse_next(s) +/// u24(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305))); /// assert_eq!(be_u24(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_u24 = |s| { -/// u24(winnow::number::Endianness::Little).parse_next(s) +/// u24(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300))); @@ -1384,24 +1384,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u24; +/// use winnow::binary::u24; /// /// let be_u24 = |s| { -/// u24::<_,Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// u24::<_,Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305))); /// assert_eq!(be_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2)))); /// /// let le_u24 = |s| { -/// u24::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// u24::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300))); /// assert_eq!(le_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2)))); /// ``` #[inline(always)] -pub fn u24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u32, E> +pub fn u24<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1409,20 +1409,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_u24, - crate::number::Endianness::Little => le_u24, + Endianness::Big => be_u24, + Endianness::Little => le_u24, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_u24, + Endianness::Native => be_u24, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_u24, + Endianness::Native => le_u24, } }(input) } /// Recognizes an unsigned 4 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian u32 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian u32 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u32 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u32 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1434,17 +1434,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u32; +/// use winnow::binary::u32; /// /// let be_u32 = |s| { -/// u32(winnow::number::Endianness::Big).parse_next(s) +/// u32(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507))); /// assert_eq!(be_u32(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_u32 = |s| { -/// u32(winnow::number::Endianness::Little).parse_next(s) +/// u32(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300))); @@ -1456,24 +1456,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u32; +/// use winnow::binary::u32; /// /// let be_u32 = |s| { -/// u32::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// u32::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507))); /// assert_eq!(be_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3)))); /// /// let le_u32 = |s| { -/// u32::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// u32::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300))); /// assert_eq!(le_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3)))); /// ``` #[inline(always)] -pub fn u32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u32, E> +pub fn u32<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1481,20 +1481,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_u32, - crate::number::Endianness::Little => le_u32, + Endianness::Big => be_u32, + Endianness::Little => le_u32, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_u32, + Endianness::Native => be_u32, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_u32, + Endianness::Native => le_u32, } }(input) } /// Recognizes an unsigned 8 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian u64 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian u64 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u64 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u64 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1506,17 +1506,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u64; +/// use winnow::binary::u64; /// /// let be_u64 = |s| { -/// u64(winnow::number::Endianness::Big).parse_next(s) +/// u64(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607))); /// assert_eq!(be_u64(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_u64 = |s| { -/// u64(winnow::number::Endianness::Little).parse_next(s) +/// u64(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100))); @@ -1528,24 +1528,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u64; +/// use winnow::binary::u64; /// /// let be_u64 = |s| { -/// u64::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// u64::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607))); /// assert_eq!(be_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7)))); /// /// let le_u64 = |s| { -/// u64::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// u64::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100))); /// assert_eq!(le_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7)))); /// ``` #[inline(always)] -pub fn u64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u64, E> +pub fn u64<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, u64, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1553,20 +1553,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_u64, - crate::number::Endianness::Little => le_u64, + Endianness::Big => be_u64, + Endianness::Little => le_u64, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_u64, + Endianness::Native => be_u64, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_u64, + Endianness::Native => le_u64, } }(input) } /// Recognizes an unsigned 16 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian u128 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian u128 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u128 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u128 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1578,17 +1578,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::u128; +/// use winnow::binary::u128; /// /// let be_u128 = |s| { -/// u128(winnow::number::Endianness::Big).parse_next(s) +/// u128(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607))); /// assert_eq!(be_u128(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_u128 = |s| { -/// u128(winnow::number::Endianness::Little).parse_next(s) +/// u128(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100))); @@ -1600,24 +1600,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::u128; +/// use winnow::binary::u128; /// /// let be_u128 = |s| { -/// u128::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// u128::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_u128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00010203040506070001020304050607))); /// assert_eq!(be_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15)))); /// /// let le_u128 = |s| { -/// u128::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// u128::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_u128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07060504030201000706050403020100))); /// assert_eq!(le_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15)))); /// ``` #[inline(always)] -pub fn u128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u128, E> +pub fn u128<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, u128, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1625,12 +1625,12 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_u128, - crate::number::Endianness::Little => le_u128, + Endianness::Big => be_u128, + Endianness::Little => le_u128, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_u128, + Endianness::Native => be_u128, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_u128, + Endianness::Native => le_u128, } }(input) } @@ -1649,7 +1649,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i8; +/// use winnow::binary::i8; /// /// fn parser(s: &[u8]) -> IResult<&[u8], i8> { /// i8.parse_next(s) @@ -1664,7 +1664,7 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i8; +/// use winnow::binary::i8; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> { /// i8.parse_next(s) @@ -1680,10 +1680,10 @@ where I: Stream<Token = u8>, { trace("i8", move |input: I| { - if input.is_partial() { - streaming_u8(input) + if <I as StreamIsPartial>::is_partial_supported() { + u8_::<_, _, true>(input) } else { - complete_u8(input) + u8_::<_, _, false>(input) } .map(|(i, n)| (i, n as i8)) }) @@ -1692,8 +1692,8 @@ where /// Recognizes a signed 2 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian i16 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian i16 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i16 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i16 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1705,17 +1705,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i16; +/// use winnow::binary::i16; /// /// let be_i16 = |s| { -/// i16(winnow::number::Endianness::Big).parse_next(s) +/// i16(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003))); /// assert_eq!(be_i16(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_i16 = |s| { -/// i16(winnow::number::Endianness::Little).parse_next(s) +/// i16(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300))); @@ -1727,24 +1727,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i16; +/// use winnow::binary::i16; /// /// let be_i16 = |s| { -/// i16::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// i16::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003))); /// assert_eq!(be_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// /// let le_i16 = |s| { -/// i16::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// i16::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300))); /// assert_eq!(le_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// ``` #[inline(always)] -pub fn i16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i16, E> +pub fn i16<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, i16, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1752,20 +1752,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_i16, - crate::number::Endianness::Little => le_i16, + Endianness::Big => be_i16, + Endianness::Little => le_i16, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_i16, + Endianness::Native => be_i16, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_i16, + Endianness::Native => le_i16, } }(input) } /// Recognizes a signed 3 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian i24 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian i24 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i24 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i24 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1777,17 +1777,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i24; +/// use winnow::binary::i24; /// /// let be_i24 = |s| { -/// i24(winnow::number::Endianness::Big).parse_next(s) +/// i24(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305))); /// assert_eq!(be_i24(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_i24 = |s| { -/// i24(winnow::number::Endianness::Little).parse_next(s) +/// i24(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300))); @@ -1799,24 +1799,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i24; +/// use winnow::binary::i24; /// /// let be_i24 = |s| { -/// i24::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// i24::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305))); /// assert_eq!(be_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2)))); /// /// let le_i24 = |s| { -/// i24::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// i24::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300))); /// assert_eq!(le_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2)))); /// ``` #[inline(always)] -pub fn i24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i32, E> +pub fn i24<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1824,20 +1824,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_i24, - crate::number::Endianness::Little => le_i24, + Endianness::Big => be_i24, + Endianness::Little => le_i24, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_i24, + Endianness::Native => be_i24, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_i24, + Endianness::Native => le_i24, } }(input) } /// Recognizes a signed 4 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian i32 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian i32 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i32 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i32 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1849,17 +1849,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i32; +/// use winnow::binary::i32; /// /// let be_i32 = |s| { -/// i32(winnow::number::Endianness::Big).parse_next(s) +/// i32(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507))); /// assert_eq!(be_i32(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_i32 = |s| { -/// i32(winnow::number::Endianness::Little).parse_next(s) +/// i32(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300))); @@ -1871,24 +1871,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i32; +/// use winnow::binary::i32; /// /// let be_i32 = |s| { -/// i32::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// i32::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507))); /// assert_eq!(be_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3)))); /// /// let le_i32 = |s| { -/// i32::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// i32::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300))); /// assert_eq!(le_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3)))); /// ``` #[inline(always)] -pub fn i32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i32, E> +pub fn i32<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1896,20 +1896,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_i32, - crate::number::Endianness::Little => le_i32, + Endianness::Big => be_i32, + Endianness::Little => le_i32, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_i32, + Endianness::Native => be_i32, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_i32, + Endianness::Native => le_i32, } }(input) } /// Recognizes a signed 8 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian i64 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian i64 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i64 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i64 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1921,17 +1921,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i64; +/// use winnow::binary::i64; /// /// let be_i64 = |s| { -/// i64(winnow::number::Endianness::Big).parse_next(s) +/// i64(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607))); /// assert_eq!(be_i64(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_i64 = |s| { -/// i64(winnow::number::Endianness::Little).parse_next(s) +/// i64(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100))); @@ -1943,24 +1943,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i64; +/// use winnow::binary::i64; /// /// let be_i64 = |s| { -/// i64::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// i64::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607))); /// assert_eq!(be_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7)))); /// /// let le_i64 = |s| { -/// i64::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// i64::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100))); /// assert_eq!(le_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7)))); /// ``` #[inline(always)] -pub fn i64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i64, E> +pub fn i64<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, i64, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -1968,20 +1968,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_i64, - crate::number::Endianness::Little => le_i64, + Endianness::Big => be_i64, + Endianness::Little => le_i64, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_i64, + Endianness::Native => be_i64, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_i64, + Endianness::Native => le_i64, } }(input) } /// Recognizes a signed 16 byte integer /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian i128 integer, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian i128 integer. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i128 integer, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i128 integer. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -1993,17 +1993,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::i128; +/// use winnow::binary::i128; /// /// let be_i128 = |s| { -/// i128(winnow::number::Endianness::Big).parse_next(s) +/// i128(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607))); /// assert_eq!(be_i128(&b"\x01"[..]), Err(ErrMode::Backtrack(Error::new(&[0x01][..], ErrorKind::Slice)))); /// /// let le_i128 = |s| { -/// i128(winnow::number::Endianness::Little).parse_next(s) +/// i128(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100))); @@ -2015,24 +2015,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::i128; +/// use winnow::binary::i128; /// /// let be_i128 = |s| { -/// i128::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// i128::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00010203040506070001020304050607))); /// assert_eq!(be_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15)))); /// /// let le_i128 = |s| { -/// i128::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// i128::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07060504030201000706050403020100))); /// assert_eq!(le_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15)))); /// ``` #[inline(always)] -pub fn i128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i128, E> +pub fn i128<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, i128, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -2040,12 +2040,12 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_i128, - crate::number::Endianness::Little => le_i128, + Endianness::Big => be_i128, + Endianness::Little => le_i128, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_i128, + Endianness::Native => be_i128, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_i128, + Endianness::Native => le_i128, } }(input) } @@ -2063,7 +2063,7 @@ where /// # use winnow::prelude::*; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_f32; +/// use winnow::binary::be_f32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], f32> { /// be_f32.parse_next(s) @@ -2077,7 +2077,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_f32; +/// use winnow::binary::be_f32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> { /// be_f32.parse_next(s) @@ -2111,7 +2111,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::be_f64; +/// use winnow::binary::be_f64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], f64> { /// be_f64.parse_next(s) @@ -2125,7 +2125,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::be_f64; +/// use winnow::binary::be_f64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> { /// be_f64::<_, Error<_>>.parse_next(s) @@ -2159,7 +2159,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_f32; +/// use winnow::binary::le_f32; /// /// fn parser(s: &[u8]) -> IResult<&[u8], f32> { /// le_f32.parse_next(s) @@ -2173,7 +2173,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_f32; +/// use winnow::binary::le_f32; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> { /// le_f32::<_, Error<_>>.parse_next(s) @@ -2207,7 +2207,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::le_f64; +/// use winnow::binary::le_f64; /// /// fn parser(s: &[u8]) -> IResult<&[u8], f64> { /// le_f64.parse_next(s) @@ -2221,7 +2221,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::number::le_f64; +/// use winnow::binary::le_f64; /// /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> { /// le_f64::<_, Error<_>>.parse_next(s) @@ -2245,8 +2245,8 @@ where /// Recognizes a 4 byte floating point number /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian f32 float, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian f32 float. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f32 float, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian f32 float. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -2258,17 +2258,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::f32; +/// use winnow::binary::f32; /// /// let be_f32 = |s| { -/// f32(winnow::number::Endianness::Big).parse_next(s) +/// f32(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_f32(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5))); /// assert_eq!(be_f32(&b"abc"[..]), Err(ErrMode::Backtrack(Error::new(&b"abc"[..], ErrorKind::Slice)))); /// /// let le_f32 = |s| { -/// f32(winnow::number::Endianness::Little).parse_next(s) +/// f32(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_f32(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5))); @@ -2280,24 +2280,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::f32; +/// use winnow::binary::f32; /// /// let be_f32 = |s| { -/// f32::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// f32::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_f32(Partial::new(&[0x41, 0x48, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5))); /// assert_eq!(be_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// /// let le_f32 = |s| { -/// f32::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// f32::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_f32(Partial::new(&[0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 12.5))); /// assert_eq!(le_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1)))); /// ``` #[inline(always)] -pub fn f32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, f32, E> +pub fn f32<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, f32, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -2305,20 +2305,20 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_f32, - crate::number::Endianness::Little => le_f32, + Endianness::Big => be_f32, + Endianness::Little => le_f32, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_f32, + Endianness::Native => be_f32, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_f32, + Endianness::Native => le_f32, } }(input) } /// Recognizes an 8 byte floating point number /// -/// If the parameter is `winnow::number::Endianness::Big`, parse a big endian f64 float, -/// otherwise if `winnow::number::Endianness::Little` parse a little endian f64 float. +/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f64 float, +/// otherwise if `winnow::binary::Endianness::Little` parse a little endian f64 float. /// /// *Complete version*: returns an error if there is not enough input data /// @@ -2330,17 +2330,17 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::number::f64; +/// use winnow::binary::f64; /// /// let be_f64 = |s| { -/// f64(winnow::number::Endianness::Big).parse_next(s) +/// f64(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_f64(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5))); /// assert_eq!(be_f64(&b"abc"[..]), Err(ErrMode::Backtrack(Error::new(&b"abc"[..], ErrorKind::Slice)))); /// /// let le_f64 = |s| { -/// f64(winnow::number::Endianness::Little).parse_next(s) +/// f64(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5))); @@ -2352,24 +2352,24 @@ where /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// # use winnow::Partial; -/// use winnow::number::f64; +/// use winnow::binary::f64; /// /// let be_f64 = |s| { -/// f64::<_, Error<_>>(winnow::number::Endianness::Big).parse_next(s) +/// f64::<_, Error<_>>(winnow::binary::Endianness::Big).parse_next(s) /// }; /// /// assert_eq!(be_f64(Partial::new(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5))); /// assert_eq!(be_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5)))); /// /// let le_f64 = |s| { -/// f64::<_, Error<_>>(winnow::number::Endianness::Little).parse_next(s) +/// f64::<_, Error<_>>(winnow::binary::Endianness::Little).parse_next(s) /// }; /// /// assert_eq!(le_f64(Partial::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..])), Ok((Partial::new(&b""[..]), 12.5))); /// assert_eq!(le_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5)))); /// ``` #[inline(always)] -pub fn f64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, f64, E> +pub fn f64<I, E: ParseError<I>>(endian: Endianness) -> impl Parser<I, f64, E> where I: StreamIsPartial, I: Stream<Token = u8>, @@ -2377,12 +2377,174 @@ where { move |input: I| { match endian { - crate::number::Endianness::Big => be_f64, - crate::number::Endianness::Little => le_f64, + Endianness::Big => be_f64, + Endianness::Little => le_f64, #[cfg(target_endian = "big")] - crate::number::Endianness::Native => be_f64, + Endianness::Native => be_f64, #[cfg(target_endian = "little")] - crate::number::Endianness::Native => le_f64, + Endianness::Native => le_f64, } }(input) } + +/// Gets a number from the parser and returns a +/// subslice of the input of that size. +/// +/// *Complete version*: Returns an error if there is not enough input data. +/// +/// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data. +/// +/// # Arguments +/// * `f` The parser to apply. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed, stream::Partial}; +/// # use winnow::prelude::*; +/// use winnow::Bytes; +/// use winnow::binary::be_u16; +/// use winnow::binary::length_data; +/// use winnow::token::tag; +/// +/// type Stream<'i> = Partial<&'i Bytes>; +/// +/// fn stream(b: &[u8]) -> Stream<'_> { +/// Partial::new(Bytes::new(b)) +/// } +/// +/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> { +/// length_data(be_u16).parse_next(s) +/// } +/// +/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..]))); +/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2)))); +/// ``` +pub fn length_data<I, N, E, F>(mut f: F) -> impl Parser<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + N: ToUsize, + F: Parser<I, N, E>, + E: ParseError<I>, +{ + trace("length_data", move |i: I| { + let (i, length) = f.parse_next(i)?; + + crate::token::take(length).parse_next(i) + }) +} + +/// Gets a number from the first parser, +/// takes a subslice of the input of that size, +/// then applies the second parser on that subslice. +/// If the second parser returns `Incomplete`, +/// `length_value` will return an error. +/// +/// *Complete version*: Returns an error if there is not enough input data. +/// +/// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data. +/// +/// # Arguments +/// * `f` The parser to apply. +/// * `g` The parser to apply on the subslice. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed, stream::{Partial, StreamIsPartial}}; +/// # use winnow::prelude::*; +/// use winnow::Bytes; +/// use winnow::binary::be_u16; +/// use winnow::binary::length_value; +/// use winnow::token::tag; +/// +/// type Stream<'i> = Partial<&'i Bytes>; +/// +/// fn stream(b: &[u8]) -> Stream<'_> { +/// Partial::new(Bytes::new(b)) +/// } +/// +/// fn complete_stream(b: &[u8]) -> Stream<'_> { +/// let mut p = Partial::new(Bytes::new(b)); +/// let _ = p.complete(); +/// p +/// } +/// +/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> { +/// length_value(be_u16, "abc").parse_next(s) +/// } +/// +/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..]))); +/// assert_eq!(parser(stream(b"\x00\x03123123")), Err(ErrMode::Backtrack(Error::new(complete_stream(&b"123"[..]), ErrorKind::Tag)))); +/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2)))); +/// ``` +pub fn length_value<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, O, E> +where + I: StreamIsPartial, + I: Stream + UpdateSlice, + N: ToUsize, + F: Parser<I, N, E>, + G: Parser<I, O, E>, + E: ParseError<I>, +{ + trace("length_value", move |i: I| { + let (i, data) = length_data(f.by_ref()).parse_next(i)?; + let mut data = I::update_slice(i.clone(), data); + let _ = data.complete(); + let (_, o) = g.by_ref().complete_err().parse_next(data)?; + Ok((i, o)) + }) +} + +/// Gets a number from the first parser, +/// then applies the second parser that many times. +/// +/// # Arguments +/// * `f` The parser to apply to obtain the count. +/// * `g` The parser to apply repeatedly. +/// +/// # Example +/// +/// ```rust +/// # #[cfg(feature = "std")] { +/// # use winnow::prelude::*; +/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// # use winnow::prelude::*; +/// use winnow::Bytes; +/// use winnow::binary::u8; +/// use winnow::binary::length_count; +/// use winnow::token::tag; +/// +/// type Stream<'i> = &'i Bytes; +/// +/// fn stream(b: &[u8]) -> Stream<'_> { +/// Bytes::new(b) +/// } +/// +/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, Vec<&[u8]>> { +/// length_count(u8.map(|i| { +/// println!("got number: {}", i); +/// i +/// }), "abc").parse_next(s) +/// } +/// +/// assert_eq!(parser(stream(b"\x02abcabcabc")), Ok((stream(b"abc"), vec![&b"abc"[..], &b"abc"[..]]))); +/// assert_eq!(parser(stream(b"\x03123123123")), Err(ErrMode::Backtrack(Error::new(stream(b"123123123"), ErrorKind::Tag)))); +/// # } +/// ``` +pub fn length_count<I, O, C, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, C, E> +where + I: Stream, + N: ToUsize, + C: Accumulate<O>, + F: Parser<I, N, E>, + G: Parser<I, O, E>, + E: ParseError<I>, +{ + trace("length_count", move |i: I| { + let (i, n) = f.parse_next(i)?; + let n = n.to_usize(); + repeat(n, g.by_ref()).parse_next(i) + }) +} diff --git a/vendor/winnow/src/number/tests.rs b/vendor/winnow/src/binary/tests.rs index bbfeb239e..4307d88fe 100644 --- a/vendor/winnow/src/number/tests.rs +++ b/vendor/winnow/src/binary/tests.rs @@ -295,7 +295,7 @@ mod complete { #[test] fn configurable_endianness() { - use crate::number::Endianness; + use crate::binary::Endianness; fn be_tst16(i: &[u8]) -> IResult<&[u8], u16> { u16(Endianness::Big).parse_next(i) @@ -382,7 +382,16 @@ mod partial { use crate::error::ErrMode; use crate::error::Error; use crate::error::Needed; + #[cfg(feature = "alloc")] + use crate::lib::std::vec::Vec; use crate::Partial; + use crate::{ + ascii::digit1 as digit, + binary::{be_u16, be_u8}, + error::ErrorKind, + lib::std::str::{self, FromStr}, + IResult, + }; macro_rules! assert_parse( ($left: expr, $right: expr) => { @@ -955,7 +964,7 @@ mod partial { #[test] fn configurable_endianness() { - use crate::number::Endianness; + use crate::binary::Endianness; fn be_tst16(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> { u16(Endianness::Big).parse_next(i) @@ -1055,4 +1064,151 @@ mod partial { Ok((Partial::new(&b""[..]), 36_028_874_334_732_032_i64)) ); } + + #[test] + #[cfg(feature = "alloc")] + fn length_count_test() { + fn number(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { + digit + .try_map(str::from_utf8) + .try_map(FromStr::from_str) + .parse_next(i) + } + + fn cnt(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + length_count(number, "abc").parse_next(i) + } + + assert_eq!( + cnt(Partial::new(&b"2abcabcabcdef"[..])), + Ok((Partial::new(&b"abcdef"[..]), vec![&b"abc"[..], &b"abc"[..]])) + ); + assert_eq!( + cnt(Partial::new(&b"2ab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + cnt(Partial::new(&b"3abcab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + cnt(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Slice + ))) + ); + assert_eq!( + cnt(Partial::new(&b"2abcxxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + } + + #[test] + fn length_data_test() { + fn number(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { + digit + .try_map(str::from_utf8) + .try_map(FromStr::from_str) + .parse_next(i) + } + + fn take(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { + length_data(number).parse_next(i) + } + + assert_eq!( + take(Partial::new(&b"6abcabcabcdef"[..])), + Ok((Partial::new(&b"abcdef"[..]), &b"abcabc"[..])) + ); + assert_eq!( + take(Partial::new(&b"3ab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + take(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Slice + ))) + ); + assert_eq!( + take(Partial::new(&b"2abcxxx"[..])), + Ok((Partial::new(&b"cxxx"[..]), &b"ab"[..])) + ); + } + + #[test] + fn length_value_test() { + use crate::stream::StreamIsPartial; + + fn length_value_1(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> { + length_value(be_u8, be_u16).parse_next(i) + } + fn length_value_2(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u8, u8)> { + length_value(be_u8, (be_u8, be_u8)).parse_next(i) + } + + let mut empty_complete = Partial::new(&b""[..]); + let _ = empty_complete.complete(); + + let i1 = [0, 5, 6]; + assert_eq!( + length_value_1(Partial::new(&i1)), + Err(ErrMode::Backtrack(error_position!( + empty_complete, + ErrorKind::Slice + ))) + ); + assert_eq!( + length_value_2(Partial::new(&i1)), + Err(ErrMode::Backtrack(error_position!( + empty_complete, + ErrorKind::Token + ))) + ); + + let i2 = [1, 5, 6, 3]; + { + let mut middle_complete = Partial::new(&i2[1..2]); + let _ = middle_complete.complete(); + assert_eq!( + length_value_1(Partial::new(&i2)), + Err(ErrMode::Backtrack(error_position!( + middle_complete, + ErrorKind::Slice + ))) + ); + assert_eq!( + length_value_2(Partial::new(&i2)), + Err(ErrMode::Backtrack(error_position!( + empty_complete, + ErrorKind::Token + ))) + ); + } + + let i3 = [2, 5, 6, 3, 4, 5, 7]; + assert_eq!( + length_value_1(Partial::new(&i3)), + Ok((Partial::new(&i3[3..]), 1286)) + ); + assert_eq!( + length_value_2(Partial::new(&i3)), + Ok((Partial::new(&i3[3..]), (5, 6))) + ); + + let i4 = [3, 5, 6, 3, 4, 5]; + assert_eq!( + length_value_1(Partial::new(&i4)), + Ok((Partial::new(&i4[4..]), 1286)) + ); + assert_eq!( + length_value_2(Partial::new(&i4)), + Ok((Partial::new(&i4[4..]), (5, 6))) + ); + } } diff --git a/vendor/winnow/src/bits.rs b/vendor/winnow/src/bits.rs new file mode 100644 index 000000000..6b4981f30 --- /dev/null +++ b/vendor/winnow/src/bits.rs @@ -0,0 +1,71 @@ +//! Deprecated, see [`binary::bits`] +#![deprecated(since = "0.4.2", note = "Replaced with `binary::bits`")] + +use crate::binary; +use crate::error::{ErrorConvert, ParseError}; +use crate::lib::std::ops::{AddAssign, Shl, Shr}; +use crate::stream::{AsBytes, Stream, StreamIsPartial, ToUsize}; +use crate::{IResult, Parser}; + +/// Deprecated, replaced with [`binary::bits::bits`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::bits::bits`")] +#[inline(always)] +pub fn bits<I, O, E1, E2, P>(parser: P) -> impl Parser<I, O, E2> +where + E1: ParseError<(I, usize)> + ErrorConvert<E2>, + E2: ParseError<I>, + I: Stream, + P: Parser<(I, usize), O, E1>, +{ + binary::bits::bits(parser) +} + +/// Deprecated, replaced with [`binary::bits::bytes`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::bits::bytes`")] +#[inline(always)] +pub fn bytes<I, O, E1, E2, P>(parser: P) -> impl Parser<(I, usize), O, E2> +where + E1: ParseError<I> + ErrorConvert<E2>, + E2: ParseError<(I, usize)>, + I: Stream<Token = u8>, + P: Parser<I, O, E1>, +{ + binary::bits::bytes(parser) +} + +/// Deprecated, replaced with [`binary::bits::take`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::bits::take`")] +#[inline(always)] +pub fn take<I, O, C, E: ParseError<(I, usize)>>(count: C) -> impl Parser<(I, usize), O, E> +where + I: Stream<Token = u8> + AsBytes + StreamIsPartial, + C: ToUsize, + O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>, +{ + binary::bits::take(count) +} + +/// Deprecated, replaced with [`binary::bits::tag`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::bits::tag`")] +#[inline(always)] +pub fn tag<I, O, C, E: ParseError<(I, usize)>>( + pattern: O, + count: C, +) -> impl Parser<(I, usize), O, E> +where + I: Stream<Token = u8> + AsBytes + StreamIsPartial, + C: ToUsize, + O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq, +{ + binary::bits::tag(pattern, count) +} + +/// Deprecated, replaced with [`binary::bits::bool`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::bits::bool`")] +#[inline(always)] +pub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E> +where + I: Stream<Token = u8> + AsBytes + StreamIsPartial, +{ + binary::bits::bool(input) +} diff --git a/vendor/winnow/src/branch.rs b/vendor/winnow/src/branch.rs new file mode 100644 index 000000000..0783262b4 --- /dev/null +++ b/vendor/winnow/src/branch.rs @@ -0,0 +1,10 @@ +//! Deprecated, see [`combinator`] +#![deprecated(since = "0.4.2", note = "Replaced with `combinator`")] + +use crate::combinator; + +pub use combinator::alt; +pub use combinator::dispatch; +pub use combinator::permutation; +pub use combinator::Alt; +pub use combinator::Permutation; diff --git a/vendor/winnow/src/branch/tests.rs b/vendor/winnow/src/branch/tests.rs deleted file mode 100644 index 80bc163ce..000000000 --- a/vendor/winnow/src/branch/tests.rs +++ /dev/null @@ -1,180 +0,0 @@ -use crate::branch::{alt, permutation}; - -use crate::error::ErrMode; -use crate::error::ErrorKind; -use crate::error::Needed; -use crate::IResult; -use crate::Parser; -use crate::Partial; -#[cfg(feature = "alloc")] -use crate::{ - error::ParseError, - lib::std::{ - fmt::Debug, - string::{String, ToString}, - }, -}; - -#[cfg(feature = "alloc")] -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct ErrorStr(String); - -#[cfg(feature = "alloc")] -impl From<u32> for ErrorStr { - fn from(i: u32) -> Self { - ErrorStr(format!("custom error code: {}", i)) - } -} - -#[cfg(feature = "alloc")] -impl<'a> From<&'a str> for ErrorStr { - fn from(i: &'a str) -> Self { - ErrorStr(format!("custom error message: {}", i)) - } -} - -#[cfg(feature = "alloc")] -impl<I: Debug> ParseError<I> for ErrorStr { - fn from_error_kind(input: I, kind: ErrorKind) -> Self { - ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind)) - } - - fn append(self, input: I, kind: ErrorKind) -> Self { - ErrorStr(format!( - "custom error message: ({:?}, {:?}) - {:?}", - input, kind, self - )) - } -} - -#[cfg(feature = "alloc")] -#[test] -fn alt_test() { - fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - Ok((&b""[..], input)) - } - - #[allow(unused_variables)] - fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - Err(ErrMode::Backtrack(ErrorStr("abcd".to_string()))) - } - - fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - Ok((input, &b""[..])) - } - - fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - alt((dont_work, dont_work)).parse_next(i) - } - fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - alt((dont_work, work)).parse_next(i) - } - fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { - alt((dont_work, dont_work, work2, dont_work)).parse_next(i) - } - //named!(alt1, alt!(dont_work | dont_work)); - //named!(alt2, alt!(dont_work | work)); - //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work)); - - let a = &b"abcd"[..]; - assert_eq!( - alt1(a), - Err(ErrMode::Backtrack(error_node_position!( - a, - ErrorKind::Alt, - ErrorStr("abcd".to_string()) - ))) - ); - assert_eq!(alt2(a), Ok((&b""[..], a))); - assert_eq!(alt3(a), Ok((a, &b""[..]))); - - fn alt4(i: &[u8]) -> IResult<&[u8], &[u8]> { - alt(("abcd", "efgh")).parse_next(i) - } - let b = &b"efgh"[..]; - assert_eq!(alt4(a), Ok((&b""[..], a))); - assert_eq!(alt4(b), Ok((&b""[..], b))); -} - -#[test] -fn alt_incomplete() { - fn alt1(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - alt(("a", "bc", "def")).parse_next(i) - } - - let a = &b""[..]; - assert_eq!( - alt1(Partial::new(a)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - let a = &b"b"[..]; - assert_eq!( - alt1(Partial::new(a)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - let a = &b"bcd"[..]; - assert_eq!( - alt1(Partial::new(a)), - Ok((Partial::new(&b"d"[..]), &b"bc"[..])) - ); - let a = &b"cde"[..]; - assert_eq!( - alt1(Partial::new(a)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(a), - ErrorKind::Tag - ))) - ); - let a = &b"de"[..]; - assert_eq!( - alt1(Partial::new(a)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - let a = &b"defg"[..]; - assert_eq!( - alt1(Partial::new(a)), - Ok((Partial::new(&b"g"[..]), &b"def"[..])) - ); -} - -#[test] -fn permutation_test() { - #[allow(clippy::type_complexity)] - fn perm(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (&[u8], &[u8], &[u8])> { - permutation(("abcd", "efg", "hi")).parse_next(i) - } - - let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); - - let a = &b"abcdefghijk"[..]; - assert_eq!( - perm(Partial::new(a)), - Ok((Partial::new(&b"jk"[..]), expected)) - ); - let b = &b"efgabcdhijk"[..]; - assert_eq!( - perm(Partial::new(b)), - Ok((Partial::new(&b"jk"[..]), expected)) - ); - let c = &b"hiefgabcdjk"[..]; - assert_eq!( - perm(Partial::new(c)), - Ok((Partial::new(&b"jk"[..]), expected)) - ); - - let d = &b"efgxyzabcdefghi"[..]; - assert_eq!( - perm(Partial::new(d)), - Err(ErrMode::Backtrack(error_node_position!( - Partial::new(&b"efgxyzabcdefghi"[..]), - ErrorKind::Alt, - error_position!(Partial::new(&b"xyzabcdefghi"[..]), ErrorKind::Tag) - ))) - ); - - let e = &b"efgabc"[..]; - assert_eq!( - perm(Partial::new(e)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); -} diff --git a/vendor/winnow/src/bytes.rs b/vendor/winnow/src/bytes.rs new file mode 100644 index 000000000..9f57a56d2 --- /dev/null +++ b/vendor/winnow/src/bytes.rs @@ -0,0 +1,26 @@ +//! Deprecated, see [`token`] +#![deprecated(since = "0.4.2", note = "Replaced with `token`")] + +use crate::error::ParseError; +use crate::stream::StreamIsPartial; +use crate::stream::{ContainsToken, Stream}; +use crate::token; +use crate::Parser; + +pub use crate::token::*; + +/// Deprecated, see [`token::take_while`] +#[deprecated(since = "0.4.2", note = "Replaced with `token::take_while`")] +#[inline(always)] +pub fn take_while_m_n<T, I, Error: ParseError<I>>( + m: usize, + n: usize, + list: T, +) -> impl Parser<I, <I as Stream>::Slice, Error> +where + I: StreamIsPartial, + I: Stream, + T: ContainsToken<<I as Stream>::Token>, +{ + token::take_while(m..=n, list) +} diff --git a/vendor/winnow/src/character.rs b/vendor/winnow/src/character.rs new file mode 100644 index 000000000..a2f685971 --- /dev/null +++ b/vendor/winnow/src/character.rs @@ -0,0 +1,342 @@ +//! Deprecated, see [`ascii`] +#![deprecated(since = "0.4.2", note = "Replaced with `ascii`")] + +use crate::ascii; +use crate::error::ParseError; +use crate::stream::Compare; +use crate::stream::ContainsToken; +use crate::stream::{AsBStr, AsChar, Offset, ParseSlice, Stream, StreamIsPartial}; +use crate::IResult; +use crate::Parser; + +/// Deprecated, replaced by [`ascii::crlf`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::crlf`")] +#[inline(always)] +pub fn crlf<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + I: Compare<&'static str>, +{ + ascii::crlf.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::not_line_ending`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::not_line_ending`")] +#[inline(always)] +pub fn not_line_ending<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream + AsBStr, + I: Compare<&'static str>, + <I as Stream>::Token: AsChar, +{ + ascii::not_line_ending.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::line_ending`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::line_ending`")] +#[inline(always)] +pub fn line_ending<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + I: Compare<&'static str>, +{ + ascii::line_ending.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::newline`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::newline`")] +#[inline(always)] +pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::newline.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::tab`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::tab`")] +#[inline(always)] +pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::tab.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::alpha0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::alpha0`")] +#[inline(always)] +pub fn alpha0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::alpha0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::alpha1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::alpha1`")] +#[inline(always)] +pub fn alpha1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::alpha1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::digit0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::digit0`")] +#[inline(always)] +pub fn digit0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::digit0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::digit1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::digit1`")] +#[inline(always)] +pub fn digit1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::digit1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::hex_digit0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::hex_digit0`")] +#[inline(always)] +pub fn hex_digit0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::hex_digit0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::hex_digit1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::hex_digit1`")] +#[inline(always)] +pub fn hex_digit1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::hex_digit1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::oct_digit0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::oct_digit0`")] +#[inline(always)] +pub fn oct_digit0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::oct_digit0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::oct_digit1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::oct_digit1`")] +#[inline(always)] +pub fn oct_digit1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::oct_digit0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::alphanumeric0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::alphanumeric0`")] +#[inline(always)] +pub fn alphanumeric0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::alphanumeric0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::alphanumeric1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::alphanumeric1`")] +#[inline(always)] +pub fn alphanumeric1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar, +{ + ascii::alphanumeric1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::space0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::space0`")] +#[inline(always)] +pub fn space0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::space0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::space1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::space1`")] +#[inline(always)] +pub fn space1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::space1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::multispace0`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::multispace0`")] +#[inline(always)] +pub fn multispace0<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::multispace0.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::multispace1`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::multispace1`")] +#[inline(always)] +pub fn multispace1<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, +{ + ascii::multispace1.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::dec_uint`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::dec_uint`")] +#[inline(always)] +pub fn dec_uint<I, O, E: ParseError<I>>(input: I) -> IResult<I, O, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, + O: Uint, +{ + ascii::dec_uint.parse_next(input) +} + +pub use ascii::Uint; + +/// Deprecated, replaced by [`ascii::dec_int`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::dec_int`")] +#[inline(always)] +pub fn dec_int<I, O, E: ParseError<I>>(input: I) -> IResult<I, O, E> +where + I: StreamIsPartial, + I: Stream, + <I as Stream>::Token: AsChar + Copy, + O: Int, +{ + ascii::dec_int.parse_next(input) +} + +pub use ascii::Int; + +/// Deprecated, replaced by [`ascii::hex_uint`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::hex_uint`")] +#[inline(always)] +pub fn hex_uint<I, O, E: ParseError<I>>(input: I) -> IResult<I, O, E> +where + I: StreamIsPartial, + I: Stream, + O: HexUint, + <I as Stream>::Token: AsChar, + <I as Stream>::Slice: AsBStr, +{ + ascii::hex_uint.parse_next(input) +} + +pub use ascii::HexUint; + +/// Deprecated, replaced by [`ascii::float`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::float`")] +#[inline(always)] +pub fn float<I, O, E: ParseError<I>>(input: I) -> IResult<I, O, E> +where + I: StreamIsPartial, + I: Stream, + I: Offset + Compare<&'static str>, + <I as Stream>::Slice: ParseSlice<O>, + <I as Stream>::Token: AsChar + Copy, + <I as Stream>::IterOffsets: Clone, + I: AsBStr, + &'static str: ContainsToken<<I as Stream>::Token>, +{ + ascii::float.parse_next(input) +} + +/// Deprecated, replaced by [`ascii::escaped`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::escaped`")] +#[inline(always)] +pub fn escaped<'a, I: 'a, Error, F, G, O1, O2>( + normal: F, + control_char: char, + escapable: G, +) -> impl Parser<I, <I as Stream>::Slice, Error> +where + I: StreamIsPartial, + I: Stream + Offset, + <I as Stream>::Token: crate::stream::AsChar, + F: Parser<I, O1, Error>, + G: Parser<I, O2, Error>, + Error: ParseError<I>, +{ + ascii::escaped(normal, control_char, escapable) +} + +#[cfg(feature = "alloc")] +/// Deprecated, replaced by [`ascii::escaped_transform`] +#[deprecated(since = "0.4.2", note = "Replaced with `ascii::escaped_transform`")] +#[inline(always)] +pub fn escaped_transform<I, Error, F, G, Output>( + normal: F, + control_char: char, + transform: G, +) -> impl Parser<I, Output, Error> +where + I: StreamIsPartial, + I: Stream + Offset, + <I as Stream>::Token: crate::stream::AsChar, + Output: crate::stream::Accumulate<<I as Stream>::Slice>, + F: Parser<I, <I as Stream>::Slice, Error>, + G: Parser<I, <I as Stream>::Slice, Error>, + Error: ParseError<I>, +{ + ascii::escaped_transform(normal, control_char, transform) +} diff --git a/vendor/winnow/src/branch/mod.rs b/vendor/winnow/src/combinator/branch.rs index 6a2c9bc3a..042b27d53 100644 --- a/vendor/winnow/src/branch/mod.rs +++ b/vendor/winnow/src/combinator/branch.rs @@ -1,14 +1,7 @@ -//! Choice combinators - -#[cfg(test)] -mod tests; - -use crate::error::ErrMode; -use crate::error::ErrorKind; -use crate::error::ParseError; +use crate::error::{ErrMode, ErrorKind, ParseError}; use crate::stream::Stream; use crate::trace::trace; -use crate::{IResult, Parser}; +use crate::*; #[doc(inline)] pub use crate::dispatch; @@ -34,8 +27,8 @@ pub trait Alt<I, O, E> { /// ```rust /// # use winnow::{error::ErrMode, error::Error,error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::character::{alpha1, digit1}; -/// use winnow::branch::alt; +/// use winnow::ascii::{alpha1, digit1}; +/// use winnow::combinator::alt; /// # fn main() { /// fn parser(input: &str) -> IResult<&str, &str> { /// alt((alpha1, digit1)).parse_next(input) @@ -75,8 +68,8 @@ pub trait Permutation<I, O, E> { /// ```rust /// # use winnow::{error::ErrMode,error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::character::{alpha1, digit1}; -/// use winnow::branch::permutation; +/// use winnow::ascii::{alpha1, digit1}; +/// use winnow::combinator::permutation; /// # fn main() { /// fn parser(input: &str) -> IResult<&str, (&str, &str)> { /// permutation((alpha1, digit1)).parse_next(input) @@ -98,8 +91,8 @@ pub trait Permutation<I, O, E> { /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}}; /// # use winnow::prelude::*; -/// use winnow::branch::permutation; -/// use winnow::bytes::any; +/// use winnow::combinator::permutation; +/// use winnow::token::any; /// /// fn parser(input: &str) -> IResult<&str, (char, char)> { /// permutation((any, 'a')).parse_next(input) diff --git a/vendor/winnow/src/combinator/core.rs b/vendor/winnow/src/combinator/core.rs new file mode 100644 index 000000000..75551d7c5 --- /dev/null +++ b/vendor/winnow/src/combinator/core.rs @@ -0,0 +1,490 @@ +use crate::error::{ErrMode, ErrorKind, Needed, ParseError}; +use crate::stream::Stream; +use crate::trace::trace; +use crate::*; + +/// Return the remaining input. +/// +/// # Example +/// +/// ```rust +/// # use winnow::error::ErrorKind; +/// # use winnow::error::Error; +/// use winnow::combinator::rest; +/// assert_eq!(rest::<_,Error<_>>("abc"), Ok(("", "abc"))); +/// assert_eq!(rest::<_,Error<_>>(""), Ok(("", ""))); +/// ``` +#[inline] +pub fn rest<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: Stream, +{ + trace("rest", move |input: I| { + Ok(input.next_slice(input.eof_offset())) + }) + .parse_next(input) +} + +/// Return the length of the remaining input. +/// +/// Note: this does not advance the [`Stream`] +/// +/// # Example +/// +/// ```rust +/// # use winnow::error::ErrorKind; +/// # use winnow::error::Error; +/// use winnow::combinator::rest_len; +/// assert_eq!(rest_len::<_,Error<_>>("abc"), Ok(("abc", 3))); +/// assert_eq!(rest_len::<_,Error<_>>(""), Ok(("", 0))); +/// ``` +#[inline] +pub fn rest_len<I, E: ParseError<I>>(input: I) -> IResult<I, usize, E> +where + I: Stream, +{ + trace("rest_len", move |input: I| { + let len = input.eof_offset(); + Ok((input, len)) + }) + .parse_next(input) +} + +/// Apply a [`Parser`], producing `None` on [`ErrMode::Backtrack`]. +/// +/// To chain an error up, see [`cut_err`]. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; +/// # use winnow::prelude::*; +/// use winnow::combinator::opt; +/// use winnow::ascii::alpha1; +/// # fn main() { +/// +/// fn parser(i: &str) -> IResult<&str, Option<&str>> { +/// opt(alpha1).parse_next(i) +/// } +/// +/// assert_eq!(parser("abcd;"), Ok((";", Some("abcd")))); +/// assert_eq!(parser("123;"), Ok(("123;", None))); +/// # } +/// ``` +pub fn opt<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl Parser<I, Option<O>, E> +where + F: Parser<I, O, E>, +{ + trace("opt", move |input: I| { + let i = input.clone(); + match f.parse_next(input) { + Ok((i, o)) => Ok((i, Some(o))), + Err(ErrMode::Backtrack(_)) => Ok((i, None)), + Err(e) => Err(e), + } + }) +} + +/// Calls the parser if the condition is met. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult}; +/// # use winnow::prelude::*; +/// use winnow::combinator::cond; +/// use winnow::ascii::alpha1; +/// # fn main() { +/// +/// fn parser(b: bool, i: &str) -> IResult<&str, Option<&str>> { +/// cond(b, alpha1).parse_next(i) +/// } +/// +/// assert_eq!(parser(true, "abcd;"), Ok((";", Some("abcd")))); +/// assert_eq!(parser(false, "abcd;"), Ok(("abcd;", None))); +/// assert_eq!(parser(true, "123;"), Err(ErrMode::Backtrack(Error::new("123;", ErrorKind::Slice)))); +/// assert_eq!(parser(false, "123;"), Ok(("123;", None))); +/// # } +/// ``` +pub fn cond<I, O, E: ParseError<I>, F>(b: bool, mut f: F) -> impl Parser<I, Option<O>, E> +where + I: Stream, + F: Parser<I, O, E>, +{ + trace("cond", move |input: I| { + if b { + match f.parse_next(input) { + Ok((i, o)) => Ok((i, Some(o))), + Err(e) => Err(e), + } + } else { + Ok((input, None)) + } + }) +} + +/// Tries to apply its parser without consuming the input. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; +/// # use winnow::prelude::*; +/// use winnow::combinator::peek; +/// use winnow::ascii::alpha1; +/// # fn main() { +/// +/// let mut parser = peek(alpha1); +/// +/// assert_eq!(parser.parse_next("abcd;"), Ok(("abcd;", "abcd"))); +/// assert_eq!(parser.parse_next("123;"), Err(ErrMode::Backtrack(Error::new("123;", ErrorKind::Slice)))); +/// # } +/// ``` +#[doc(alias = "look_ahead")] +#[doc(alias = "rewind")] +pub fn peek<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl Parser<I, O, E> +where + F: Parser<I, O, E>, +{ + trace("peek", move |input: I| { + let i = input.clone(); + match f.parse_next(input) { + Ok((_, o)) => Ok((i, o)), + Err(e) => Err(e), + } + }) +} + +/// Match the end of the [`Stream`] +/// +/// Otherwise, it will error. +/// +/// # Example +/// +/// ```rust +/// # use std::str; +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; +/// # use winnow::combinator::eof; +/// # use winnow::prelude::*; +/// +/// let mut parser = eof; +/// assert_eq!(parser.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Eof)))); +/// assert_eq!(parser.parse_next(""), Ok(("", ""))); +/// ``` +#[doc(alias = "end")] +#[doc(alias = "eoi")] +pub fn eof<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> +where + I: Stream, +{ + trace("eof", move |input: I| { + if input.eof_offset() == 0 { + Ok(input.next_slice(0)) + } else { + Err(ErrMode::from_error_kind(input, ErrorKind::Eof)) + } + }) + .parse_next(input) +} + +/// Succeeds if the child parser returns an error. +/// +/// **Note:** This does not advance the [`Stream`] +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; +/// # use winnow::prelude::*; +/// use winnow::combinator::not; +/// use winnow::ascii::alpha1; +/// # fn main() { +/// +/// let mut parser = not(alpha1); +/// +/// assert_eq!(parser.parse_next("123"), Ok(("123", ()))); +/// assert_eq!(parser.parse_next("abcd"), Err(ErrMode::Backtrack(Error::new("abcd", ErrorKind::Not)))); +/// # } +/// ``` +pub fn not<I: Stream, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, (), E> +where + F: Parser<I, O, E>, +{ + trace("not", move |input: I| { + let i = input.clone(); + match parser.parse_next(input) { + Ok(_) => Err(ErrMode::from_error_kind(i, ErrorKind::Not)), + Err(ErrMode::Backtrack(_)) => Ok((i, ())), + Err(e) => Err(e), + } + }) +} + +/// Transforms an [`ErrMode::Backtrack`] (recoverable) to [`ErrMode::Cut`] (unrecoverable) +/// +/// This commits the parse result, preventing alternative branch paths like with +/// [`winnow::combinator::alt`][crate::combinator::alt]. +/// +/// # Example +/// +/// Without `cut_err`: +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; +/// # use winnow::token::one_of; +/// # use winnow::ascii::digit1; +/// # use winnow::combinator::rest; +/// # use winnow::combinator::alt; +/// # use winnow::combinator::preceded; +/// # use winnow::prelude::*; +/// # fn main() { +/// +/// fn parser(input: &str) -> IResult<&str, &str> { +/// alt(( +/// preceded(one_of("+-"), digit1), +/// rest +/// )).parse_next(input) +/// } +/// +/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); +/// assert_eq!(parser("ab"), Ok(("", "ab"))); +/// assert_eq!(parser("+"), Ok(("", "+"))); +/// # } +/// ``` +/// +/// With `cut_err`: +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; +/// # use winnow::prelude::*; +/// # use winnow::token::one_of; +/// # use winnow::ascii::digit1; +/// # use winnow::combinator::rest; +/// # use winnow::combinator::alt; +/// # use winnow::combinator::preceded; +/// use winnow::combinator::cut_err; +/// # fn main() { +/// +/// fn parser(input: &str) -> IResult<&str, &str> { +/// alt(( +/// preceded(one_of("+-"), cut_err(digit1)), +/// rest +/// )).parse_next(input) +/// } +/// +/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); +/// assert_eq!(parser("ab"), Ok(("", "ab"))); +/// assert_eq!(parser("+"), Err(ErrMode::Cut(Error { input: "", kind: ErrorKind::Slice }))); +/// # } +/// ``` +pub fn cut_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, O, E> +where + I: Stream, + F: Parser<I, O, E>, +{ + trace("cut_err", move |input: I| { + parser.parse_next(input).map_err(|e| e.cut()) + }) +} + +/// Transforms an [`ErrMode::Cut`] (unrecoverable) to [`ErrMode::Backtrack`] (recoverable) +/// +/// This attempts the parse, allowing other parsers to be tried on failure, like with +/// [`winnow::combinator::alt`][crate::combinator::alt]. +pub fn backtrack_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, O, E> +where + I: Stream, + F: Parser<I, O, E>, +{ + trace("backtrack_err", move |input: I| { + parser.parse_next(input).map_err(|e| e.backtrack()) + }) +} + +/// A placeholder for a not-yet-implemented [`Parser`] +/// +/// This is analogous to the [`todo!`] macro and helps with prototyping. +/// +/// # Panic +/// +/// This will panic when parsing +/// +/// # Example +/// +/// ```rust +/// # use winnow::prelude::*; +/// # use winnow::combinator::todo; +/// +/// fn parser(input: &str) -> IResult<&str, u64> { +/// todo(input) +/// } +/// ``` +#[track_caller] +pub fn todo<I, O, E>(input: I) -> IResult<I, O, E> +where + I: Stream, +{ + #![allow(clippy::todo)] + trace("todo", move |_input: I| todo!("unimplemented parse")).parse_next(input) +} + +/// Repeats the embedded parser, lazily returning the results +/// +/// Call the iterator's [`ParserIterator::finish`] method to get the remaining input if successful, +/// or the error value if we encountered an error. +/// +/// On [`ErrMode::Backtrack`], iteration will stop. To instead chain an error up, see [`cut_err`]. +/// +/// # Example +/// +/// ```rust +/// use winnow::{combinator::iterator, IResult, token::tag, ascii::alpha1, combinator::terminated}; +/// use std::collections::HashMap; +/// +/// let data = "abc|defg|hijkl|mnopqr|123"; +/// let mut it = iterator(data, terminated(alpha1, "|")); +/// +/// let parsed = it.map(|v| (v, v.len())).collect::<HashMap<_,_>>(); +/// let res: IResult<_,_> = it.finish(); +/// +/// assert_eq!(parsed, [("abc", 3usize), ("defg", 4), ("hijkl", 5), ("mnopqr", 6)].iter().cloned().collect()); +/// assert_eq!(res, Ok(("123", ()))); +/// ``` +pub fn iterator<I, O, E, F>(input: I, parser: F) -> ParserIterator<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream, + E: ParseError<I>, +{ + ParserIterator { + parser, + input, + state: Some(State::Running), + o: Default::default(), + } +} + +/// Main structure associated to [`iterator`]. +pub struct ParserIterator<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream, +{ + parser: F, + input: I, + state: Option<State<E>>, + o: core::marker::PhantomData<O>, +} + +impl<F, I, O, E> ParserIterator<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream, +{ + /// Returns the remaining input if parsing was successful, or the error if we encountered an error. + pub fn finish(mut self) -> IResult<I, (), E> { + match self.state.take().unwrap() { + State::Running | State::Done => Ok((self.input, ())), + State::Failure(e) => Err(ErrMode::Cut(e)), + State::Incomplete(i) => Err(ErrMode::Incomplete(i)), + } + } +} + +impl<'a, F, I, O, E> core::iter::Iterator for &'a mut ParserIterator<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream, +{ + type Item = O; + + fn next(&mut self) -> Option<Self::Item> { + if let State::Running = self.state.take().unwrap() { + let input = self.input.clone(); + + match self.parser.parse_next(input) { + Ok((i, o)) => { + self.input = i; + self.state = Some(State::Running); + Some(o) + } + Err(ErrMode::Backtrack(_)) => { + self.state = Some(State::Done); + None + } + Err(ErrMode::Cut(e)) => { + self.state = Some(State::Failure(e)); + None + } + Err(ErrMode::Incomplete(i)) => { + self.state = Some(State::Incomplete(i)); + None + } + } + } else { + None + } + } +} + +enum State<E> { + Running, + Done, + Failure(E), + Incomplete(Needed), +} + +/// Always succeeds with given value without consuming any input. +/// +/// For example, it can be used as the last alternative in `alt` to +/// specify the default case. +/// +/// **Note:** This never advances the [`Stream`] +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; +/// # use winnow::prelude::*; +/// use winnow::combinator::alt; +/// use winnow::combinator::success; +/// +/// let mut parser = success::<_,_,Error<_>>(10); +/// assert_eq!(parser.parse_next("xyz"), Ok(("xyz", 10))); +/// +/// fn sign(input: &str) -> IResult<&str, isize> { +/// alt(( +/// '-'.value(-1), +/// '+'.value(1), +/// success::<_,_,Error<_>>(1) +/// )).parse_next(input) +/// } +/// assert_eq!(sign("+10"), Ok(("10", 1))); +/// assert_eq!(sign("-10"), Ok(("10", -1))); +/// assert_eq!(sign("10"), Ok(("10", 1))); +/// ``` +#[doc(alias = "value")] +#[doc(alias = "empty")] +pub fn success<I: Stream, O: Clone, E: ParseError<I>>(val: O) -> impl Parser<I, O, E> { + trace("success", move |input: I| Ok((input, val.clone()))) +} + +/// A parser which always fails. +/// +/// For example, it can be used as the last alternative in `alt` to +/// control the error message given. +/// +/// # Example +/// +/// ```rust +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; +/// use winnow::combinator::fail; +/// +/// let s = "string"; +/// assert_eq!(fail::<_, &str, _>(s), Err(ErrMode::Backtrack(Error::new(s, ErrorKind::Fail)))); +/// ``` +#[doc(alias = "unexpected")] +pub fn fail<I: Stream, O, E: ParseError<I>>(i: I) -> IResult<I, O, E> { + trace("fail", |i| { + Err(ErrMode::from_error_kind(i, ErrorKind::Fail)) + }) + .parse_next(i) +} diff --git a/vendor/winnow/src/combinator/mod.rs b/vendor/winnow/src/combinator/mod.rs index 4276b06d3..d76ef8e5f 100644 --- a/vendor/winnow/src/combinator/mod.rs +++ b/vendor/winnow/src/combinator/mod.rs @@ -8,45 +8,41 @@ //! //! | combinator | usage | input | output | comment | //! |---|---|---|---|---| -//! | [`one_of`][crate::bytes::one_of] | `one_of("abc")` | `"abc"` | `Ok(("bc", 'a'))` |Matches one of the provided characters (works with non ASCII characters too)| -//! | [`none_of`][crate::bytes::none_of] | `none_of("abc")` | `"xyab"` | `Ok(("yab", 'x'))` |Matches anything but the provided characters| -//! | [`tag`][crate::bytes::tag] | `"hello"` | `"hello world"` | `Ok((" world", "hello"))` |Recognizes a specific suite of characters or bytes| -//! | [`tag_no_case`][crate::bytes::tag_no_case] | `tag_no_case("hello")` | `"HeLLo World"` | `Ok((" World", "HeLLo"))` |Case insensitive comparison. Note that case insensitive comparison is not well defined for unicode, and that you might have bad surprises| -//! | [`take`][crate::bytes::take] | `take(4)` | `"hello"` | `Ok(("o", "hell"))` |Takes a specific number of bytes or characters| -//! | [`take_while0`][crate::bytes::take_while0] | `take_while0(is_alphabetic)` | `"abc123"` | `Ok(("123", "abc"))` |Returns the longest list of bytes for which the provided pattern matches. `take_while1` does the same, but must return at least one character| -//! | [`take_till0`][crate::bytes::take_till0] | `take_till0(is_alphabetic)` | `"123abc"` | `Ok(("abc", "123"))` |Returns the longest list of bytes or characters until the provided pattern matches. `take_till1` does the same, but must return at least one character. This is the reverse behaviour from `take_while0`: `take_till(f)` is equivalent to `take_while0(\|c\| !f(c))`| -//! | [`take_until0`][crate::bytes::take_until0] | `take_until0("world")` | `"Hello world"` | `Ok(("world", "Hello "))` |Returns the longest list of bytes or characters until the provided tag is found. `take_until1` does the same, but must return at least one character| +//! | [`one_of`][crate::token::one_of] | `one_of("abc")` | `"abc"` | `Ok(("bc", 'a'))` |Matches one of the provided characters (works with non ASCII characters too)| +//! | [`none_of`][crate::token::none_of] | `none_of("abc")` | `"xyab"` | `Ok(("yab", 'x'))` |Matches anything but the provided characters| +//! | [`tag`][crate::token::tag] | `"hello"` | `"hello world"` | `Ok((" world", "hello"))` |Recognizes a specific suite of characters or bytes| +//! | [`tag_no_case`][crate::token::tag_no_case] | `tag_no_case("hello")` | `"HeLLo World"` | `Ok((" World", "HeLLo"))` |Case insensitive comparison. Note that case insensitive comparison is not well defined for unicode, and that you might have bad surprises| +//! | [`take`][crate::token::take] | `take(4)` | `"hello"` | `Ok(("o", "hell"))` |Takes a specific number of bytes or characters| +//! | [`take_while`][crate::token::take_while] | `take_while(0.., is_alphabetic)` | `"abc123"` | `Ok(("123", "abc"))` |Returns the longest list of bytes for which the provided pattern matches.| +//! | [`take_till0`][crate::token::take_till0] | `take_till0(is_alphabetic)` | `"123abc"` | `Ok(("abc", "123"))` |Returns the longest list of bytes or characters until the provided pattern matches. `take_till1` does the same, but must return at least one character. This is the reverse behaviour from `take_while`: `take_till(f)` is equivalent to `take_while(0.., \|c\| !f(c))`| +//! | [`take_until0`][crate::token::take_until0] | `take_until0("world")` | `"Hello world"` | `Ok(("world", "Hello "))` |Returns the longest list of bytes or characters until the provided tag is found. `take_until1` does the same, but must return at least one character| //! //! ## Choice combinators //! //! | combinator | usage | input | output | comment | //! |---|---|---|---|---| -//! | [`alt`][crate::branch::alt] | `alt(("ab", "cd"))` | `"cdef"` | `Ok(("ef", "cd"))` |Try a list of parsers and return the result of the first successful one| -//! | [`dispatch`][crate::branch::dispatch] | \- | \- | \- | `match` for parsers | -//! | [`permutation`][crate::branch::permutation] | `permutation(("ab", "cd", "12"))` | `"cd12abc"` | `Ok(("c", ("ab", "cd", "12"))` |Succeeds when all its child parser have succeeded, whatever the order| +//! | [`alt`][crate::combinator::alt] | `alt(("ab", "cd"))` | `"cdef"` | `Ok(("ef", "cd"))` |Try a list of parsers and return the result of the first successful one| +//! | [`dispatch`][crate::combinator::dispatch] | \- | \- | \- | `match` for parsers | +//! | [`permutation`][crate::combinator::permutation] | `permutation(("ab", "cd", "12"))` | `"cd12abc"` | `Ok(("c", ("ab", "cd", "12"))` |Succeeds when all its child parser have succeeded, whatever the order| //! //! ## Sequence combinators //! //! | combinator | usage | input | output | comment | //! |---|---|---|---|---| //! | [`(...)` (tuples)][crate::Parser] | `("ab", "XY", take(1))` | `"abXYZ!"` | `Ok(("!", ("ab", "XY", "Z")))` |Chains parsers and assemble the sub results in a tuple. You can use as many child parsers as you can put elements in a tuple| -//! | [`delimited`][crate::sequence::delimited] | `delimited(char('('), take(2), char(')'))` | `"(ab)cd"` | `Ok(("cd", "ab"))` || -//! | [`preceded`][crate::sequence::preceded] | `preceded("ab", "XY")` | `"abXYZ"` | `Ok(("Z", "XY"))` || -//! | [`terminated`][crate::sequence::terminated] | `terminated("ab", "XY")` | `"abXYZ"` | `Ok(("Z", "ab"))` || -//! | [`separated_pair`][crate::sequence::separated_pair] | `separated_pair("hello", char(','), "world")` | `"hello,world!"` | `Ok(("!", ("hello", "world")))` || +//! | [`delimited`] | `delimited(char('('), take(2), char(')'))` | `"(ab)cd"` | `Ok(("cd", "ab"))` || +//! | [`preceded`] | `preceded("ab", "XY")` | `"abXYZ"` | `Ok(("Z", "XY"))` || +//! | [`terminated`] | `terminated("ab", "XY")` | `"abXYZ"` | `Ok(("Z", "ab"))` || +//! | [`separated_pair`] | `separated_pair("hello", char(','), "world")` | `"hello,world!"` | `Ok(("!", ("hello", "world")))` || //! //! ## Applying a parser multiple times //! //! | combinator | usage | input | output | comment | //! |---|---|---|---|---| -//! | [`count`][crate::multi::count] | `count(take(2), 3)` | `"abcdefgh"` | `Ok(("gh", vec!["ab", "cd", "ef"]))` |Applies the child parser a specified number of times| -//! | [`many0`][crate::multi::many0] | `many0("ab")` | `"abababc"` | `Ok(("c", vec!["ab", "ab", "ab"]))` |Applies the parser 0 or more times and returns the list of results in a Vec. `many1` does the same operation but must return at least one element| -//! | [`many_m_n`][crate::multi::many_m_n] | `many_m_n(1, 3, "ab")` | `"ababc"` | `Ok(("c", vec!["ab", "ab"]))` |Applies the parser between m and n times (n included) and returns the list of results in a Vec| -//! | [`many_till0`][crate::multi::many_till0] | `many_till0(tag( "ab" ), tag( "ef" ))` | `"ababefg"` | `Ok(("g", (vec!["ab", "ab"], "ef")))` |Applies the first parser until the second applies. Returns a tuple containing the list of results from the first in a Vec and the result of the second| -//! | [`separated0`][crate::multi::separated0] | `separated0("ab", ",")` | `"ab,ab,ab."` | `Ok((".", vec!["ab", "ab", "ab"]))` |`separated1` works like `separated0` but must returns at least one element| -//! | [`fold_many0`][crate::multi::fold_many0] | `fold_many0(be_u8, \|\| 0, \|acc, item\| acc + item)` | `[1, 2, 3]` | `Ok(([], 6))` |Applies the parser 0 or more times and folds the list of return values. The `fold_many1` version must apply the child parser at least one time| -//! | [`fold_many_m_n`][crate::multi::fold_many_m_n] | `fold_many_m_n(1, 2, be_u8, \|\| 0, \|acc, item\| acc + item)` | `[1, 2, 3]` | `Ok(([3], 3))` |Applies the parser between m and n times (n included) and folds the list of return value| -//! | [`length_count`][crate::multi::length_count] | `length_count(number, "ab")` | `"2ababab"` | `Ok(("ab", vec!["ab", "ab"]))` |Gets a number from the first parser, then applies the second parser that many times| +//! | [`repeat`][crate::combinator::repeat] | `repeat(1..=3, "ab")` | `"ababc"` | `Ok(("c", vec!["ab", "ab"]))` |Applies the parser between m and n times (n included) and returns the list of results in a Vec| +//! | [`repeat_till0`][crate::combinator::repeat_till0] | `repeat_till0(tag( "ab" ), tag( "ef" ))` | `"ababefg"` | `Ok(("g", (vec!["ab", "ab"], "ef")))` |Applies the first parser until the second applies. Returns a tuple containing the list of results from the first in a Vec and the result of the second| +//! | [`separated0`][crate::combinator::separated0] | `separated0("ab", ",")` | `"ab,ab,ab."` | `Ok((".", vec!["ab", "ab", "ab"]))` |`separated1` works like `separated0` but must returns at least one element| +//! | [`fold_repeat`][crate::combinator::fold_repeat] | `fold_repeat(1..=2, be_u8, \|\| 0, \|acc, item\| acc + item)` | `[1, 2, 3]` | `Ok(([3], 3))` |Applies the parser between m and n times (n included) and folds the list of return value| //! //! ## Partial related //! @@ -61,7 +57,7 @@ //! - [`Parser::map`][crate::Parser::map]: method to map a function on the result of a parser //! - [`Parser::and_then`][crate::Parser::and_then]: Applies a second parser over the output of the first one //! - [`Parser::verify_map`][Parser::verify_map]: Maps a function returning an `Option` on the output of a parser -//! - [`Parser::map_res`][Parser::map_res]: Maps a function returning a `Result` on the output of a parser +//! - [`Parser::try_map`][Parser::try_map]: Maps a function returning a `Result` on the output of a parser //! - [`Parser::parse_to`][crate::Parser::parse_to]: Apply [`std::str::FromStr`] to the output of the parser //! - [`not`][not]: Returns a result only if the embedded parser returns `Backtrack` or `Incomplete`. Does not consume the input //! - [`opt`][opt]: Make the underlying parser optional @@ -89,33 +85,33 @@ //! //! ## Text parsing //! -//! - [`any`][crate::bytes::any]: Matches one token -//! - [`tab`][crate::character::tab]: Matches a tab character `\t` -//! - [`crlf`][crate::character::crlf]: Recognizes the string `\r\n` -//! - [`line_ending`][crate::character::line_ending]: Recognizes an end of line (both `\n` and `\r\n`) -//! - [`newline`][crate::character::newline]: Matches a newline character `\n` -//! - [`not_line_ending`][crate::character::not_line_ending]: Recognizes a string of any char except `\r` or `\n` +//! - [`any`][crate::token::any]: Matches one token +//! - [`tab`][crate::ascii::tab]: Matches a tab character `\t` +//! - [`crlf`][crate::ascii::crlf]: Recognizes the string `\r\n` +//! - [`line_ending`][crate::ascii::line_ending]: Recognizes an end of line (both `\n` and `\r\n`) +//! - [`newline`][crate::ascii::newline]: Matches a newline character `\n` +//! - [`not_line_ending`][crate::ascii::not_line_ending]: Recognizes a string of any char except `\r` or `\n` //! - [`rest`][rest]: Return the remaining input //! -//! - [`alpha0`][crate::character::alpha0]: Recognizes zero or more lowercase and uppercase alphabetic characters: `[a-zA-Z]`. [`alpha1`][crate::character::alpha1] does the same but returns at least one character -//! - [`alphanumeric0`][crate::character::alphanumeric0]: Recognizes zero or more numerical and alphabetic characters: `[0-9a-zA-Z]`. [`alphanumeric1`][crate::character::alphanumeric1] does the same but returns at least one character -//! - [`space0`][crate::character::space0]: Recognizes zero or more spaces and tabs. [`space1`][crate::character::space1] does the same but returns at least one character -//! - [`multispace0`][crate::character::multispace0]: Recognizes zero or more spaces, tabs, carriage returns and line feeds. [`multispace1`][crate::character::multispace1] does the same but returns at least one character -//! - [`digit0`][crate::character::digit0]: Recognizes zero or more numerical characters: `[0-9]`. [`digit1`][crate::character::digit1] does the same but returns at least one character -//! - [`hex_digit0`][crate::character::hex_digit0]: Recognizes zero or more hexadecimal numerical characters: `[0-9A-Fa-f]`. [`hex_digit1`][crate::character::hex_digit1] does the same but returns at least one character -//! - [`oct_digit0`][crate::character::oct_digit0]: Recognizes zero or more octal characters: `[0-7]`. [`oct_digit1`][crate::character::oct_digit1] does the same but returns at least one character +//! - [`alpha0`][crate::ascii::alpha0]: Recognizes zero or more lowercase and uppercase alphabetic characters: `[a-zA-Z]`. [`alpha1`][crate::ascii::alpha1] does the same but returns at least one character +//! - [`alphanumeric0`][crate::ascii::alphanumeric0]: Recognizes zero or more numerical and alphabetic characters: `[0-9a-zA-Z]`. [`alphanumeric1`][crate::ascii::alphanumeric1] does the same but returns at least one character +//! - [`space0`][crate::ascii::space0]: Recognizes zero or more spaces and tabs. [`space1`][crate::ascii::space1] does the same but returns at least one character +//! - [`multispace0`][crate::ascii::multispace0]: Recognizes zero or more spaces, tabs, carriage returns and line feeds. [`multispace1`][crate::ascii::multispace1] does the same but returns at least one character +//! - [`digit0`][crate::ascii::digit0]: Recognizes zero or more numerical characters: `[0-9]`. [`digit1`][crate::ascii::digit1] does the same but returns at least one character +//! - [`hex_digit0`][crate::ascii::hex_digit0]: Recognizes zero or more hexadecimal numerical characters: `[0-9A-Fa-f]`. [`hex_digit1`][crate::ascii::hex_digit1] does the same but returns at least one character +//! - [`oct_digit0`][crate::ascii::oct_digit0]: Recognizes zero or more octal characters: `[0-7]`. [`oct_digit1`][crate::ascii::oct_digit1] does the same but returns at least one character //! -//! - [`float`][crate::character::float]: Parse a floating point number in a byte string -//! - [`dec_int`][crate::character::dec_uint]: Decode a variable-width, decimal signed integer -//! - [`dec_uint`][crate::character::dec_uint]: Decode a variable-width, decimal unsigned integer -//! - [`hex_uint`][crate::character::hex_uint]: Decode a variable-width, hexadecimal integer +//! - [`float`][crate::ascii::float]: Parse a floating point number in a byte string +//! - [`dec_int`][crate::ascii::dec_uint]: Decode a variable-width, decimal signed integer +//! - [`dec_uint`][crate::ascii::dec_uint]: Decode a variable-width, decimal unsigned integer +//! - [`hex_uint`][crate::ascii::hex_uint]: Decode a variable-width, hexadecimal integer //! -//! - [`escaped`][crate::character::escaped]: Matches a byte string with escaped characters -//! - [`escaped_transform`][crate::character::escaped_transform]: Matches a byte string with escaped characters, and returns a new string with the escaped characters replaced +//! - [`escaped`][crate::ascii::escaped]: Matches a byte string with escaped characters +//! - [`escaped_transform`][crate::ascii::escaped_transform]: Matches a byte string with escaped characters, and returns a new string with the escaped characters replaced //! //! ### Character test functions //! -//! Use these functions with a combinator like `take_while0`: +//! Use these functions with a combinator like `take_while`: //! //! - [`AsChar::is_alpha`][crate::stream::AsChar::is_alpha]: Tests if byte is ASCII alphabetic: `[A-Za-z]` //! - [`AsChar::is_alphanum`][crate::stream::AsChar::is_alphanum]: Tests if byte is ASCII alphanumeric: `[A-Za-z0-9]` @@ -127,1345 +123,50 @@ //! //! ## Binary format parsing //! -//! - [`length_data`][crate::multi::length_data]: Gets a number from the first parser, then takes a subslice of the input of that size, and returns that subslice -//! - [`length_value`][crate::multi::length_value]: Gets a number from the first parser, takes a subslice of the input of that size, then applies the second parser on that subslice. If the second parser returns `Incomplete`, `length_value` will return an error +//! - [`length_count`][crate::binary::length_count] Gets a number from the first parser, then applies the second parser that many times +//! - [`length_data`][crate::binary::length_data]: Gets a number from the first parser, then takes a subslice of the input of that size, and returns that subslice +//! - [`length_value`][crate::binary::length_value]: Gets a number from the first parser, takes a subslice of the input of that size, then applies the second parser on that subslice. If the second parser returns `Incomplete`, `length_value` will return an error //! //! ### Integers //! //! Parsing integers from binary formats can be done in two ways: With parser functions, or combinators with configurable endianness. //! -//! - **configurable endianness:** [`i16`][crate::number::i16], [`i32`][crate::number::i32], -//! [`i64`][crate::number::i64], [`u16`][crate::number::u16], [`u32`][crate::number::u32], -//! [`u64`][crate::number::u64] are combinators that take as argument a -//! [`winnow::number::Endianness`][crate::number::Endianness], like this: `i16(endianness)`. If the -//! parameter is `winnow::number::Endianness::Big`, parse a big endian `i16` integer, otherwise a +//! - **configurable endianness:** [`i16`][crate::binary::i16], [`i32`][crate::binary::i32], +//! [`i64`][crate::binary::i64], [`u16`][crate::binary::u16], [`u32`][crate::binary::u32], +//! [`u64`][crate::binary::u64] are combinators that take as argument a +//! [`winnow::binary::Endianness`][crate::binary::Endianness], like this: `i16(endianness)`. If the +//! parameter is `winnow::binary::Endianness::Big`, parse a big endian `i16` integer, otherwise a //! little endian `i16` integer. //! - **fixed endianness**: The functions are prefixed by `be_` for big endian numbers, and by `le_` for little endian numbers, and the suffix is the type they parse to. As an example, `be_u32` parses a big endian unsigned integer stored in 32 bits. -//! - [`be_f32`][crate::number::be_f32], [`be_f64`][crate::number::be_f64]: Big endian floating point numbers -//! - [`le_f32`][crate::number::le_f32], [`le_f64`][crate::number::le_f64]: Little endian floating point numbers -//! - [`be_i8`][crate::number::be_i8], [`be_i16`][crate::number::be_i16], [`be_i24`][crate::number::be_i24], [`be_i32`][crate::number::be_i32], [`be_i64`][crate::number::be_i64], [`be_i128`][crate::number::be_i128]: Big endian signed integers -//! - [`be_u8`][crate::number::be_u8], [`be_u16`][crate::number::be_u16], [`be_u24`][crate::number::be_u24], [`be_u32`][crate::number::be_u32], [`be_u64`][crate::number::be_u64], [`be_u128`][crate::number::be_u128]: Big endian unsigned integers -//! - [`le_i8`][crate::number::le_i8], [`le_i16`][crate::number::le_i16], [`le_i24`][crate::number::le_i24], [`le_i32`][crate::number::le_i32], [`le_i64`][crate::number::le_i64], [`le_i128`][crate::number::le_i128]: Little endian signed integers -//! - [`le_u8`][crate::number::le_u8], [`le_u16`][crate::number::le_u16], [`le_u24`][crate::number::le_u24], [`le_u32`][crate::number::le_u32], [`le_u64`][crate::number::le_u64], [`le_u128`][crate::number::le_u128]: Little endian unsigned integers +//! - [`be_f32`][crate::binary::be_f32], [`be_f64`][crate::binary::be_f64]: Big endian floating point numbers +//! - [`le_f32`][crate::binary::le_f32], [`le_f64`][crate::binary::le_f64]: Little endian floating point numbers +//! - [`be_i8`][crate::binary::be_i8], [`be_i16`][crate::binary::be_i16], [`be_i24`][crate::binary::be_i24], [`be_i32`][crate::binary::be_i32], [`be_i64`][crate::binary::be_i64], [`be_i128`][crate::binary::be_i128]: Big endian signed integers +//! - [`be_u8`][crate::binary::be_u8], [`be_u16`][crate::binary::be_u16], [`be_u24`][crate::binary::be_u24], [`be_u32`][crate::binary::be_u32], [`be_u64`][crate::binary::be_u64], [`be_u128`][crate::binary::be_u128]: Big endian unsigned integers +//! - [`le_i8`][crate::binary::le_i8], [`le_i16`][crate::binary::le_i16], [`le_i24`][crate::binary::le_i24], [`le_i32`][crate::binary::le_i32], [`le_i64`][crate::binary::le_i64], [`le_i128`][crate::binary::le_i128]: Little endian signed integers +//! - [`le_u8`][crate::binary::le_u8], [`le_u16`][crate::binary::le_u16], [`le_u24`][crate::binary::le_u24], [`le_u32`][crate::binary::le_u32], [`le_u64`][crate::binary::le_u64], [`le_u128`][crate::binary::le_u128]: Little endian unsigned integers //! //! ### Bit stream parsing //! -//! - [`bits`][crate::bits::bits]: Transforms the current input type (byte slice `&[u8]`) to a bit stream on which bit specific parsers and more general combinators can be applied -//! - [`bytes`][crate::bits::bytes]: Transforms its bits stream input back into a byte slice for the underlying parser -//! - [`take`][crate::bits::take]: Take a set number of its -//! - [`tag`][crate::bits::tag]: Check if a set number of bis matches a pattern -//! - [`bool`][crate::bits::bool]: Match any one bit +//! - [`bits`][crate::binary::bits::bits]: Transforms the current input type (byte slice `&[u8]`) to a bit stream on which bit specific parsers and more general combinators can be applied +//! - [`bytes`][crate::binary::bits::bytes]: Transforms its bits stream input back into a byte slice for the underlying parser +//! - [`take`][crate::binary::bits::take]: Take a set number of its +//! - [`tag`][crate::binary::bits::tag]: Check if a set number of bis matches a pattern +//! - [`bool`][crate::binary::bits::bool]: Match any one bit -use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, Needed, ParseError}; -use crate::lib::std::borrow::Borrow; -use crate::lib::std::ops::Range; -use crate::stream::{Location, Stream}; -use crate::stream::{Offset, StreamIsPartial}; -use crate::trace::trace; -use crate::trace::trace_result; -use crate::*; +mod branch; +mod core; +mod multi; +mod parser; +mod sequence; #[cfg(test)] mod tests; -/// Return the remaining input. -/// -/// # Example -/// -/// ```rust -/// # use winnow::error::ErrorKind; -/// # use winnow::error::Error; -/// use winnow::combinator::rest; -/// assert_eq!(rest::<_,Error<_>>("abc"), Ok(("", "abc"))); -/// assert_eq!(rest::<_,Error<_>>(""), Ok(("", ""))); -/// ``` -#[inline] -pub fn rest<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> -where - I: Stream, -{ - trace("rest", move |input: I| { - Ok(input.next_slice(input.eof_offset())) - }) - .parse_next(input) -} +pub use self::branch::*; +pub use self::core::*; +pub use self::multi::*; +pub use self::parser::*; +pub use self::sequence::*; -/// Return the length of the remaining input. -/// -/// Note: this does not advance the [`Stream`] -/// -/// # Example -/// -/// ```rust -/// # use winnow::error::ErrorKind; -/// # use winnow::error::Error; -/// use winnow::combinator::rest_len; -/// assert_eq!(rest_len::<_,Error<_>>("abc"), Ok(("abc", 3))); -/// assert_eq!(rest_len::<_,Error<_>>(""), Ok(("", 0))); -/// ``` -#[inline] -pub fn rest_len<I, E: ParseError<I>>(input: I) -> IResult<I, usize, E> -where - I: Stream, -{ - trace("rest_len", move |input: I| { - let len = input.eof_offset(); - Ok((input, len)) - }) - .parse_next(input) -} - -/// Implementation of [`Parser::by_ref`][Parser::by_ref] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct ByRef<'p, P> { - p: &'p mut P, -} - -impl<'p, P> ByRef<'p, P> { - pub(crate) fn new(p: &'p mut P) -> Self { - Self { p } - } -} - -impl<'p, I, O, E, P: Parser<I, O, E>> Parser<I, O, E> for ByRef<'p, P> { - fn parse_next(&mut self, i: I) -> IResult<I, O, E> { - self.p.parse_next(i) - } -} - -/// Implementation of [`Parser::map`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Map<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(O) -> O2, -{ - parser: F, - map: G, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, G, I, O, O2, E> Map<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(O) -> O2, -{ - pub(crate) fn new(parser: F, map: G) -> Self { - Self { - parser, - map, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, G, I, O, O2, E> Parser<I, O2, E> for Map<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(O) -> O2, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { - match self.parser.parse_next(i) { - Err(e) => Err(e), - Ok((i, o)) => Ok((i, (self.map)(o))), - } - } -} - -/// Implementation of [`Parser::map_res`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct MapRes<F, G, I, O, O2, E, E2> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Result<O2, E2>, - I: Clone, - E: FromExternalError<I, E2>, -{ - parser: F, - map: G, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, - e2: core::marker::PhantomData<E2>, -} - -impl<F, G, I, O, O2, E, E2> MapRes<F, G, I, O, O2, E, E2> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Result<O2, E2>, - I: Clone, - E: FromExternalError<I, E2>, -{ - pub(crate) fn new(parser: F, map: G) -> Self { - Self { - parser, - map, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - e2: Default::default(), - } - } -} - -impl<F, G, I, O, O2, E, E2> Parser<I, O2, E> for MapRes<F, G, I, O, O2, E, E2> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Result<O2, E2>, - I: Clone, - E: FromExternalError<I, E2>, -{ - fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { - let i = input.clone(); - let (input, o) = self.parser.parse_next(input)?; - let res = match (self.map)(o) { - Ok(o2) => Ok((input, o2)), - Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::Verify, e)), - }; - trace_result("verify", &res); - res - } -} - -/// Implementation of [`Parser::verify_map`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct VerifyMap<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Option<O2>, - I: Clone, - E: ParseError<I>, -{ - parser: F, - map: G, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, G, I, O, O2, E> VerifyMap<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Option<O2>, - I: Clone, - E: ParseError<I>, -{ - pub(crate) fn new(parser: F, map: G) -> Self { - Self { - parser, - map, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, G, I, O, O2, E> Parser<I, O2, E> for VerifyMap<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> Option<O2>, - I: Clone, - E: ParseError<I>, -{ - fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { - let i = input.clone(); - let (input, o) = self.parser.parse_next(input)?; - let res = match (self.map)(o) { - Some(o2) => Ok((input, o2)), - None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)), - }; - trace_result("verify", &res); - res - } -} - -/// Implementation of [`Parser::and_then`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct AndThen<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Parser<O, O2, E>, - O: StreamIsPartial, -{ - outer: F, - inner: G, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, G, I, O, O2, E> AndThen<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Parser<O, O2, E>, - O: StreamIsPartial, -{ - pub(crate) fn new(outer: F, inner: G) -> Self { - Self { - outer, - inner, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, G, I, O, O2, E> Parser<I, O2, E> for AndThen<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Parser<O, O2, E>, - O: StreamIsPartial, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { - let (i, mut o) = self.outer.parse_next(i)?; - let _ = o.complete(); - let (_, o2) = self.inner.parse_next(o)?; - Ok((i, o2)) - } -} - -/// Implementation of [`Parser::parse_to`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct ParseTo<P, I, O, O2, E> -where - P: Parser<I, O, E>, - I: Stream, - O: crate::stream::ParseSlice<O2>, - E: ParseError<I>, -{ - p: P, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<P, I, O, O2, E> ParseTo<P, I, O, O2, E> -where - P: Parser<I, O, E>, - I: Stream, - O: crate::stream::ParseSlice<O2>, - E: ParseError<I>, -{ - pub(crate) fn new(p: P) -> Self { - Self { - p, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<P, I, O, O2, E> Parser<I, O2, E> for ParseTo<P, I, O, O2, E> -where - P: Parser<I, O, E>, - I: Stream, - O: crate::stream::ParseSlice<O2>, - E: ParseError<I>, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { - let input = i.clone(); - let (i, o) = self.p.parse_next(i)?; - - let res = o - .parse_slice() - .ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Verify)); - trace_result("verify", &res); - Ok((i, res?)) - } -} - -/// Implementation of [`Parser::flat_map`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct FlatMap<F, G, H, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> H, - H: Parser<I, O2, E>, -{ - f: F, - g: G, - h: core::marker::PhantomData<H>, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, G, H, I, O, O2, E> FlatMap<F, G, H, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> H, - H: Parser<I, O2, E>, -{ - pub(crate) fn new(f: F, g: G) -> Self { - Self { - f, - g, - h: Default::default(), - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, G, H, I, O, O2, E> Parser<I, O2, E> for FlatMap<F, G, H, I, O, O2, E> -where - F: Parser<I, O, E>, - G: FnMut(O) -> H, - H: Parser<I, O2, E>, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { - let (i, o) = self.f.parse_next(i)?; - (self.g)(o).parse_next(i) - } -} - -/// Apply a [`Parser`], producing `None` on [`ErrMode::Backtrack`]. -/// -/// To chain an error up, see [`cut_err`]. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::prelude::*; -/// use winnow::combinator::opt; -/// use winnow::character::alpha1; -/// # fn main() { -/// -/// fn parser(i: &str) -> IResult<&str, Option<&str>> { -/// opt(alpha1).parse_next(i) -/// } -/// -/// assert_eq!(parser("abcd;"), Ok((";", Some("abcd")))); -/// assert_eq!(parser("123;"), Ok(("123;", None))); -/// # } -/// ``` -pub fn opt<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl Parser<I, Option<O>, E> -where - F: Parser<I, O, E>, -{ - trace("opt", move |input: I| { - let i = input.clone(); - match f.parse_next(input) { - Ok((i, o)) => Ok((i, Some(o))), - Err(ErrMode::Backtrack(_)) => Ok((i, None)), - Err(e) => Err(e), - } - }) -} - -/// Calls the parser if the condition is met. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, IResult}; -/// # use winnow::prelude::*; -/// use winnow::combinator::cond; -/// use winnow::character::alpha1; -/// # fn main() { -/// -/// fn parser(b: bool, i: &str) -> IResult<&str, Option<&str>> { -/// cond(b, alpha1).parse_next(i) -/// } -/// -/// assert_eq!(parser(true, "abcd;"), Ok((";", Some("abcd")))); -/// assert_eq!(parser(false, "abcd;"), Ok(("abcd;", None))); -/// assert_eq!(parser(true, "123;"), Err(ErrMode::Backtrack(Error::new("123;", ErrorKind::Slice)))); -/// assert_eq!(parser(false, "123;"), Ok(("123;", None))); -/// # } -/// ``` -pub fn cond<I, O, E: ParseError<I>, F>(b: bool, mut f: F) -> impl Parser<I, Option<O>, E> -where - I: Stream, - F: Parser<I, O, E>, -{ - trace("cond", move |input: I| { - if b { - match f.parse_next(input) { - Ok((i, o)) => Ok((i, Some(o))), - Err(e) => Err(e), - } - } else { - Ok((input, None)) - } - }) -} - -/// Tries to apply its parser without consuming the input. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; -/// # use winnow::prelude::*; -/// use winnow::combinator::peek; -/// use winnow::character::alpha1; -/// # fn main() { -/// -/// let mut parser = peek(alpha1); -/// -/// assert_eq!(parser.parse_next("abcd;"), Ok(("abcd;", "abcd"))); -/// assert_eq!(parser.parse_next("123;"), Err(ErrMode::Backtrack(Error::new("123;", ErrorKind::Slice)))); -/// # } -/// ``` -#[doc(alias = "look_ahead")] -#[doc(alias = "rewind")] -pub fn peek<I: Stream, O, E: ParseError<I>, F>(mut f: F) -> impl Parser<I, O, E> -where - F: Parser<I, O, E>, -{ - trace("peek", move |input: I| { - let i = input.clone(); - match f.parse_next(input) { - Ok((_, o)) => Ok((i, o)), - Err(e) => Err(e), - } - }) -} - -/// Match the end of the [`Stream`] -/// -/// Otherwise, it will error. -/// -/// # Example -/// -/// ```rust -/// # use std::str; -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::combinator::eof; -/// # use winnow::prelude::*; -/// -/// let mut parser = eof; -/// assert_eq!(parser.parse_next("abc"), Err(ErrMode::Backtrack(Error::new("abc", ErrorKind::Eof)))); -/// assert_eq!(parser.parse_next(""), Ok(("", ""))); -/// ``` -#[doc(alias = "end")] -#[doc(alias = "eoi")] -pub fn eof<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Slice, E> -where - I: Stream, -{ - trace("eof", move |input: I| { - if input.eof_offset() == 0 { - Ok(input.next_slice(0)) - } else { - Err(ErrMode::from_error_kind(input, ErrorKind::Eof)) - } - }) - .parse_next(input) -} - -/// Implementation of [`Parser::complete_err`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct CompleteErr<F> { - f: F, -} - -impl<F> CompleteErr<F> { - pub(crate) fn new(f: F) -> Self { - Self { f } - } -} - -impl<F, I, O, E> Parser<I, O, E> for CompleteErr<F> -where - I: Stream, - F: Parser<I, O, E>, - E: ParseError<I>, -{ - fn parse_next(&mut self, input: I) -> IResult<I, O, E> { - trace("complete_err", |input: I| { - let i = input.clone(); - match (self.f).parse_next(input) { - Err(ErrMode::Incomplete(_)) => { - Err(ErrMode::from_error_kind(i, ErrorKind::Complete)) - } - rest => rest, - } - }) - .parse_next(input) - } -} - -/// Implementation of [`Parser::verify`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Verify<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(&O2) -> bool, - I: Clone, - O: Borrow<O2>, - O2: ?Sized, - E: ParseError<I>, -{ - parser: F, - filter: G, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, G, I, O, O2, E> Verify<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(&O2) -> bool, - I: Clone, - O: Borrow<O2>, - O2: ?Sized, - E: ParseError<I>, -{ - pub(crate) fn new(parser: F, filter: G) -> Self { - Self { - parser, - filter, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, G, I, O, O2, E> Parser<I, O, E> for Verify<F, G, I, O, O2, E> -where - F: Parser<I, O, E>, - G: Fn(&O2) -> bool, - I: Clone, - O: Borrow<O2>, - O2: ?Sized, - E: ParseError<I>, -{ - fn parse_next(&mut self, input: I) -> IResult<I, O, E> { - let i = input.clone(); - let (input, o) = self.parser.parse_next(input)?; - - let res = if (self.filter)(o.borrow()) { - Ok((input, o)) - } else { - Err(ErrMode::from_error_kind(i, ErrorKind::Verify)) - }; - trace_result("verify", &res); - res - } -} - -/// Implementation of [`Parser::value`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Value<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O2: Clone, -{ - parser: F, - val: O2, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, O2, E> Value<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O2: Clone, -{ - pub(crate) fn new(parser: F, val: O2) -> Self { - Self { - parser, - val, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, O2, E> Parser<I, O2, E> for Value<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O2: Clone, -{ - fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { - (self.parser) - .parse_next(input) - .map(|(i, _)| (i, self.val.clone())) - } -} - -/// Implementation of [`Parser::void`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Void<F, I, O, E> -where - F: Parser<I, O, E>, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E> Void<F, I, O, E> -where - F: Parser<I, O, E>, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, E> Parser<I, (), E> for Void<F, I, O, E> -where - F: Parser<I, O, E>, -{ - fn parse_next(&mut self, input: I) -> IResult<I, (), E> { - (self.parser).parse_next(input).map(|(i, _)| (i, ())) - } -} - -/// Succeeds if the child parser returns an error. -/// -/// **Note:** This does not advance the [`Stream`] -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; -/// # use winnow::prelude::*; -/// use winnow::combinator::not; -/// use winnow::character::alpha1; -/// # fn main() { -/// -/// let mut parser = not(alpha1); -/// -/// assert_eq!(parser.parse_next("123"), Ok(("123", ()))); -/// assert_eq!(parser.parse_next("abcd"), Err(ErrMode::Backtrack(Error::new("abcd", ErrorKind::Not)))); -/// # } -/// ``` -pub fn not<I: Stream, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, (), E> -where - F: Parser<I, O, E>, -{ - trace("not", move |input: I| { - let i = input.clone(); - match parser.parse_next(input) { - Ok(_) => Err(ErrMode::from_error_kind(i, ErrorKind::Not)), - Err(ErrMode::Backtrack(_)) => Ok((i, ())), - Err(e) => Err(e), - } - }) -} - -/// Implementation of [`Parser::recognize`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Recognize<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E> Recognize<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<I, O, E, F> Parser<I, <I as Stream>::Slice, E> for Recognize<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - fn parse_next(&mut self, input: I) -> IResult<I, <I as Stream>::Slice, E> { - let i = input.clone(); - match (self.parser).parse_next(i) { - Ok((i, _)) => { - let offset = input.offset_to(&i); - Ok(input.next_slice(offset)) - } - Err(e) => Err(e), - } - } -} - -/// Implementation of [`Parser::with_recognized`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct WithRecognized<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E> WithRecognized<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, E> Parser<I, (O, <I as Stream>::Slice), E> for WithRecognized<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream + Offset, -{ - fn parse_next(&mut self, input: I) -> IResult<I, (O, <I as Stream>::Slice), E> { - let i = input.clone(); - match (self.parser).parse_next(i) { - Ok((remaining, result)) => { - let offset = input.offset_to(&remaining); - let (remaining, recognized) = input.next_slice(offset); - Ok((remaining, (result, recognized))) - } - Err(e) => Err(e), - } - } -} - -/// Implementation of [`Parser::span`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Span<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E> Span<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<I, O, E, F> Parser<I, Range<usize>, E> for Span<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - fn parse_next(&mut self, input: I) -> IResult<I, Range<usize>, E> { - let start = input.location(); - self.parser.parse_next(input).map(move |(remaining, _)| { - let end = remaining.location(); - (remaining, (start..end)) - }) - } -} - -/// Implementation of [`Parser::with_span`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct WithSpan<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E> WithSpan<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, E> Parser<I, (O, Range<usize>), E> for WithSpan<F, I, O, E> -where - F: Parser<I, O, E>, - I: Clone + Location, -{ - fn parse_next(&mut self, input: I) -> IResult<I, (O, Range<usize>), E> { - let start = input.location(); - self.parser - .parse_next(input) - .map(move |(remaining, output)| { - let end = remaining.location(); - (remaining, (output, (start..end))) - }) - } -} - -/// Transforms an [`ErrMode::Backtrack`] (recoverable) to [`ErrMode::Cut`] (unrecoverable) -/// -/// This commits the parse result, preventing alternative branch paths like with -/// [`winnow::branch::alt`][crate::branch::alt]. -/// -/// # Example -/// -/// Without `cut_err`: -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::bytes::one_of; -/// # use winnow::character::digit1; -/// # use winnow::combinator::rest; -/// # use winnow::branch::alt; -/// # use winnow::sequence::preceded; -/// # use winnow::prelude::*; -/// # fn main() { -/// -/// fn parser(input: &str) -> IResult<&str, &str> { -/// alt(( -/// preceded(one_of("+-"), digit1), -/// rest -/// )).parse_next(input) -/// } -/// -/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); -/// assert_eq!(parser("ab"), Ok(("", "ab"))); -/// assert_eq!(parser("+"), Ok(("", "+"))); -/// # } -/// ``` -/// -/// With `cut_err`: -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::prelude::*; -/// # use winnow::bytes::one_of; -/// # use winnow::character::digit1; -/// # use winnow::combinator::rest; -/// # use winnow::branch::alt; -/// # use winnow::sequence::preceded; -/// use winnow::combinator::cut_err; -/// # fn main() { -/// -/// fn parser(input: &str) -> IResult<&str, &str> { -/// alt(( -/// preceded(one_of("+-"), cut_err(digit1)), -/// rest -/// )).parse_next(input) -/// } -/// -/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); -/// assert_eq!(parser("ab"), Ok(("", "ab"))); -/// assert_eq!(parser("+"), Err(ErrMode::Cut(Error { input: "", kind: ErrorKind::Slice }))); -/// # } -/// ``` -pub fn cut_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, O, E> -where - I: Stream, - F: Parser<I, O, E>, -{ - trace("cut_err", move |input: I| { - parser.parse_next(input).map_err(|e| e.cut()) - }) -} - -/// Transforms an [`ErrMode::Cut`] (unrecoverable) to [`ErrMode::Backtrack`] (recoverable) -/// -/// This attempts the parse, allowing other parsers to be tried on failure, like with -/// [`winnow::branch::alt`][crate::branch::alt]. -pub fn backtrack_err<I, O, E: ParseError<I>, F>(mut parser: F) -> impl Parser<I, O, E> -where - I: Stream, - F: Parser<I, O, E>, -{ - trace("backtrack_err", move |input: I| { - parser.parse_next(input).map_err(|e| e.backtrack()) - }) -} - -/// A placeholder for a not-yet-implemented [`Parser`] -/// -/// This is analogous to the [`todo!`] macro and helps with prototyping. -/// -/// # Panic -/// -/// This will panic when parsing -/// -/// # Example -/// -/// ```rust -/// # use winnow::prelude::*; -/// # use winnow::combinator::todo; -/// -/// fn parser(input: &str) -> IResult<&str, u64> { -/// todo(input) -/// } -/// ``` -#[track_caller] -pub fn todo<I, O, E>(input: I) -> IResult<I, O, E> -where - I: Stream, -{ - #![allow(clippy::todo)] - trace("todo", move |_input: I| todo!("unimplemented parse")).parse_next(input) -} - -/// Implementation of [`Parser::output_into`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct OutputInto<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O: Into<O2>, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - o2: core::marker::PhantomData<O2>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, O2, E> OutputInto<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O: Into<O2>, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - o2: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, O2, E> Parser<I, O2, E> for OutputInto<F, I, O, O2, E> -where - F: Parser<I, O, E>, - O: Into<O2>, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { - match self.parser.parse_next(i) { - Ok((i, o)) => Ok((i, o.into())), - Err(err) => Err(err), - } - } -} - -/// Implementation of [`Parser::err_into`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct ErrInto<F, I, O, E, E2> -where - F: Parser<I, O, E>, - E: Into<E2>, -{ - parser: F, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, - e2: core::marker::PhantomData<E2>, -} - -impl<F, I, O, E, E2> ErrInto<F, I, O, E, E2> -where - F: Parser<I, O, E>, - E: Into<E2>, -{ - pub(crate) fn new(parser: F) -> Self { - Self { - parser, - i: Default::default(), - o: Default::default(), - e: Default::default(), - e2: Default::default(), - } - } -} - -impl<F, I, O, E, E2> Parser<I, O, E2> for ErrInto<F, I, O, E, E2> -where - F: Parser<I, O, E>, - E: Into<E2>, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O, E2> { - match self.parser.parse_next(i) { - Ok(ok) => Ok(ok), - Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())), - Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())), - Err(ErrMode::Incomplete(e)) => Err(ErrMode::Incomplete(e)), - } - } -} - -/// Creates an iterator from input data and a parser. -/// -/// Call the iterator's [`ParserIterator::finish`] method to get the remaining input if successful, -/// or the error value if we encountered an error. -/// -/// On [`ErrMode::Backtrack`], iteration will stop. To instead chain an error up, see [`cut_err`]. -/// -/// # Example -/// -/// ```rust -/// use winnow::{combinator::iterator, IResult, bytes::tag, character::alpha1, sequence::terminated}; -/// use std::collections::HashMap; -/// -/// let data = "abc|defg|hijkl|mnopqr|123"; -/// let mut it = iterator(data, terminated(alpha1, "|")); -/// -/// let parsed = it.map(|v| (v, v.len())).collect::<HashMap<_,_>>(); -/// let res: IResult<_,_> = it.finish(); -/// -/// assert_eq!(parsed, [("abc", 3usize), ("defg", 4), ("hijkl", 5), ("mnopqr", 6)].iter().cloned().collect()); -/// assert_eq!(res, Ok(("123", ()))); -/// ``` -pub fn iterator<I, O, E, F>(input: I, parser: F) -> ParserIterator<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream, - E: ParseError<I>, -{ - ParserIterator { - parser, - input, - state: Some(State::Running), - o: Default::default(), - } -} - -/// Main structure associated to [`iterator`]. -pub struct ParserIterator<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream, -{ - parser: F, - input: I, - state: Option<State<E>>, - o: core::marker::PhantomData<O>, -} - -impl<F, I, O, E> ParserIterator<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream, -{ - /// Returns the remaining input if parsing was successful, or the error if we encountered an error. - pub fn finish(mut self) -> IResult<I, (), E> { - match self.state.take().unwrap() { - State::Running | State::Done => Ok((self.input, ())), - State::Failure(e) => Err(ErrMode::Cut(e)), - State::Incomplete(i) => Err(ErrMode::Incomplete(i)), - } - } -} - -impl<'a, F, I, O, E> core::iter::Iterator for &'a mut ParserIterator<F, I, O, E> -where - F: Parser<I, O, E>, - I: Stream, -{ - type Item = O; - - fn next(&mut self) -> Option<Self::Item> { - if let State::Running = self.state.take().unwrap() { - let input = self.input.clone(); - - match self.parser.parse_next(input) { - Ok((i, o)) => { - self.input = i; - self.state = Some(State::Running); - Some(o) - } - Err(ErrMode::Backtrack(_)) => { - self.state = Some(State::Done); - None - } - Err(ErrMode::Cut(e)) => { - self.state = Some(State::Failure(e)); - None - } - Err(ErrMode::Incomplete(i)) => { - self.state = Some(State::Incomplete(i)); - None - } - } - } else { - None - } - } -} - -enum State<E> { - Running, - Done, - Failure(E), - Incomplete(Needed), -} - -/// Always succeeds with given value without consuming any input. -/// -/// For example, it can be used as the last alternative in `alt` to -/// specify the default case. -/// -/// **Note:** This never advances the [`Stream`] -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::prelude::*; -/// use winnow::branch::alt; -/// use winnow::combinator::success; -/// -/// let mut parser = success::<_,_,Error<_>>(10); -/// assert_eq!(parser.parse_next("xyz"), Ok(("xyz", 10))); -/// -/// fn sign(input: &str) -> IResult<&str, isize> { -/// alt(( -/// '-'.value(-1), -/// '+'.value(1), -/// success::<_,_,Error<_>>(1) -/// )).parse_next(input) -/// } -/// assert_eq!(sign("+10"), Ok(("10", 1))); -/// assert_eq!(sign("-10"), Ok(("10", -1))); -/// assert_eq!(sign("10"), Ok(("10", 1))); -/// ``` -#[doc(alias = "value")] -#[doc(alias = "empty")] -pub fn success<I: Stream, O: Clone, E: ParseError<I>>(val: O) -> impl Parser<I, O, E> { - trace("success", move |input: I| Ok((input, val.clone()))) -} - -/// A parser which always fails. -/// -/// For example, it can be used as the last alternative in `alt` to -/// control the error message given. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult}; -/// use winnow::combinator::fail; -/// -/// let s = "string"; -/// assert_eq!(fail::<_, &str, _>(s), Err(ErrMode::Backtrack(Error::new(s, ErrorKind::Fail)))); -/// ``` -#[doc(alias = "unexpected")] -pub fn fail<I: Stream, O, E: ParseError<I>>(i: I) -> IResult<I, O, E> { - trace("fail", |i| { - Err(ErrMode::from_error_kind(i, ErrorKind::Fail)) - }) - .parse_next(i) -} - -/// Implementation of [`Parser::context`] -#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] -pub struct Context<F, I, O, E, C> -where - F: Parser<I, O, E>, - I: Stream, - E: ContextError<I, C>, - C: Clone + crate::lib::std::fmt::Debug, -{ - parser: F, - context: C, - i: core::marker::PhantomData<I>, - o: core::marker::PhantomData<O>, - e: core::marker::PhantomData<E>, -} - -impl<F, I, O, E, C> Context<F, I, O, E, C> -where - F: Parser<I, O, E>, - I: Stream, - E: ContextError<I, C>, - C: Clone + crate::lib::std::fmt::Debug, -{ - pub(crate) fn new(parser: F, context: C) -> Self { - Self { - parser, - context, - i: Default::default(), - o: Default::default(), - e: Default::default(), - } - } -} - -impl<F, I, O, E, C> Parser<I, O, E> for Context<F, I, O, E, C> -where - F: Parser<I, O, E>, - I: Stream, - E: ContextError<I, C>, - C: Clone + crate::lib::std::fmt::Debug, -{ - fn parse_next(&mut self, i: I) -> IResult<I, O, E> { - #[cfg(feature = "debug")] - let name = format!("context={:?}", self.context); - #[cfg(not(feature = "debug"))] - let name = "context"; - trace(name, move |i: I| { - (self.parser) - .parse_next(i.clone()) - .map_err(|err| err.map(|err| err.add_context(i, self.context.clone()))) - }) - .parse_next(i) - } -} +#[allow(unused_imports)] +use crate::Parser; diff --git a/vendor/winnow/src/multi/mod.rs b/vendor/winnow/src/combinator/multi.rs index 1c3aed7ba..950432601 100644 --- a/vendor/winnow/src/multi/mod.rs +++ b/vendor/winnow/src/combinator/multi.rs @@ -1,119 +1,201 @@ //! Combinators applying their child parser multiple times -#[cfg(test)] -mod tests; - use crate::error::ErrMode; use crate::error::ErrorKind; use crate::error::ParseError; use crate::stream::Accumulate; -use crate::stream::{Stream, StreamIsPartial, ToUsize, UpdateSlice}; +use crate::stream::Range; +use crate::stream::Stream; use crate::trace::trace; +use crate::IResult; use crate::Parser; /// [`Accumulate`] the output of a parser into a container, like `Vec` /// -/// This stops on [`ErrMode::Backtrack`]. To instead chain an error up, see +/// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see /// [`cut_err`][crate::combinator::cut_err]. /// +/// # Arguments +/// * `m` The minimum number of iterations. +/// * `n` The maximum number of iterations. +/// * `f` The parser to apply. +/// /// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. /// -/// **Warning:** if the parser passed in accepts empty inputs (like `alpha0` or `digit0`), `many0` will -/// return an error, to prevent going into an infinite loop +/// **Warning:** If the parser passed to `repeat` accepts empty inputs +/// (like `alpha0` or `digit0`), `repeat` will return an error, +/// to prevent going into an infinite loop. /// /// # Example /// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] +/// Zero or more reptitions: +/// ```rust +/// # #[cfg(feature = "std")] { /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::many0; -/// use winnow::bytes::tag; +/// use winnow::combinator::repeat; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// many0("abc").parse_next(s) +/// repeat(0.., "abc").parse_next(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); +/// # } /// ``` -#[doc(alias = "skip_many")] -#[doc(alias = "repeated")] -#[doc(alias = "many0_count")] -pub fn many0<I, O, C, E, F>(mut f: F) -> impl Parser<I, C, E> -where - I: Stream, - C: Accumulate<O>, - F: Parser<I, O, E>, - E: ParseError<I>, -{ - trace("many0", move |mut i: I| { - let mut acc = C::initial(None); - loop { - let len = i.eof_offset(); - match f.parse_next(i.clone()) { - Err(ErrMode::Backtrack(_)) => return Ok((i, acc)), - Err(e) => return Err(e), - Ok((i1, o)) => { - // infinite loop check: the parser must always consume - if i1.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); - } - - i = i1; - acc.accumulate(o); - } - } - } - }) -} - -/// [`Accumulate`] the output of a parser into a container, like `Vec` /// +/// One or more reptitions: +/// ```rust +/// # #[cfg(feature = "std")] { +/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// # use winnow::prelude::*; +/// use winnow::combinator::repeat; +/// use winnow::token::tag; /// -/// This stops on [`ErrMode::Backtrack`] if there is at least one result. To instead chain an error up, -/// see [`cut_err`][crate::combinator::cut_err]. +/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { +/// repeat(1.., "abc").parse_next(s) +/// } /// -/// # Arguments -/// * `f` The parser to apply. +/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); +/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); +/// assert_eq!(parser("123123"), Err(ErrMode::Backtrack(Error::new("123123", ErrorKind::Tag)))); +/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); +/// # } +/// ``` /// -/// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. +/// Fixed number of repeitions: +/// ```rust +/// # #[cfg(feature = "std")] { +/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// # use winnow::prelude::*; +/// use winnow::combinator::repeat; +/// use winnow::token::tag; /// -/// **Warning:** If the parser passed to `many1` accepts empty inputs -/// (like `alpha0` or `digit0`), `many1` will return an error, -/// to prevent going into an infinite loop. +/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { +/// repeat(2, "abc").parse_next(s) +/// } /// -/// # Example +/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); +/// assert_eq!(parser("abc123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); +/// assert_eq!(parser("123123"), Err(ErrMode::Backtrack(Error::new("123123", ErrorKind::Tag)))); +/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); +/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); +/// # } +/// ``` /// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; +/// Arbitrary reptitions: +/// ```rust +/// # #[cfg(feature = "std")] { +/// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::many1; -/// use winnow::bytes::tag; +/// use winnow::combinator::repeat; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// many1("abc").parse_next(s) +/// repeat(0..=2, "abc").parse_next(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); -/// assert_eq!(parser("123123"), Err(ErrMode::Backtrack(Error::new("123123", ErrorKind::Tag)))); -/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); +/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); +/// assert_eq!(parser(""), Ok(("", vec![]))); +/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); +/// # } /// ``` -#[doc(alias = "skip_many1")] -#[doc(alias = "repeated")] +#[doc(alias = "many0")] +#[doc(alias = "count")] +#[doc(alias = "many0_count")] +#[doc(alias = "many1")] #[doc(alias = "many1_count")] -pub fn many1<I, O, C, E, F>(mut f: F) -> impl Parser<I, C, E> +#[doc(alias = "many_m_n")] +#[doc(alias = "repeated")] +#[doc(alias = "skip_many")] +#[doc(alias = "skip_many1")] +#[inline(always)] +pub fn repeat<I, O, C, E, F>(range: impl Into<Range>, mut f: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + let Range { + start_inclusive, + end_inclusive, + } = range.into(); + trace("repeat", move |i: I| { + match (start_inclusive, end_inclusive) { + (0, None) => repeat0_(&mut f, i), + (1, None) => repeat1_(&mut f, i), + (start, end) if Some(start) == end => repeat_n_(start, &mut f, i), + (start, end) => repeat_m_n_(start, end.unwrap_or(usize::MAX), &mut f, i), + } + }) +} + +/// Deprecated, replaced by [`repeat`] +#[deprecated(since = "0.4.6", note = "Replaced with `repeat`")] +#[inline(always)] +pub fn repeat0<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + repeat(0.., f) +} + +fn repeat0_<I, O, C, E, F>(f: &mut F, mut i: I) -> IResult<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + let mut acc = C::initial(None); + loop { + let len = i.eof_offset(); + match f.parse_next(i.clone()) { + Err(ErrMode::Backtrack(_)) => return Ok((i, acc)), + Err(e) => return Err(e), + Ok((i1, o)) => { + // infinite loop check: the parser must always consume + if i1.eof_offset() == len { + return Err(ErrMode::assert(i, "`repeat` parsers must always consume")); + } + + i = i1; + acc.accumulate(o); + } + } + } +} + +/// Deprecated, replaced by [`repeat`] +#[deprecated(since = "0.4.6", note = "Replaced with `repeat`")] +#[inline(always)] +pub fn repeat1<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + repeat(1.., f) +} + +fn repeat1_<I, O, C, E, F>(f: &mut F, mut i: I) -> IResult<I, C, E> where I: Stream, C: Accumulate<O>, F: Parser<I, O, E>, E: ParseError<I>, { - trace("many1", move |mut i: I| match f.parse_next(i.clone()) { + match f.parse_next(i.clone()) { Err(e) => Err(e.append(i, ErrorKind::Many)), Ok((i1, o)) => { let mut acc = C::initial(None); @@ -128,7 +210,7 @@ where Ok((i1, o)) => { // infinite loop check: the parser must always consume if i1.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); + return Err(ErrMode::assert(i, "`repeat` parsers must always consume")); } i = i1; @@ -137,10 +219,11 @@ where } } } - }) + } } -/// Applies the parser `f` until the parser `g` produces a result. +/// [`Accumulate`] the output of parser `f` into a container, like `Vec`, until the parser `g` +/// produces a result. /// /// Returns a tuple of the results of `f` in a `Vec` and the result of `g`. /// @@ -150,15 +233,15 @@ where /// /// # Example /// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] +/// ```rust +/// # #[cfg(feature = "std")] { /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::many_till0; -/// use winnow::bytes::tag; +/// use winnow::combinator::repeat_till0; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, (Vec<&str>, &str)> { -/// many_till0("abc", "end").parse_next(s) +/// repeat_till0("abc", "end").parse_next(s) /// }; /// /// assert_eq!(parser("abcabcend"), Ok(("", (vec!["abc", "abc"], "end")))); @@ -166,8 +249,10 @@ where /// assert_eq!(parser("123123end"), Err(ErrMode::Backtrack(Error::new("123123end", ErrorKind::Tag)))); /// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("abcendefg"), Ok(("efg", (vec!["abc"], "end")))); +/// # } /// ``` -pub fn many_till0<I, O, C, P, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, (C, P), E> +#[doc(alias = "many_till0")] +pub fn repeat_till0<I, O, C, P, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, (C, P), E> where I: Stream, C: Accumulate<O>, @@ -175,7 +260,7 @@ where G: Parser<I, P, E>, E: ParseError<I>, { - trace("many_till0", move |mut i: I| { + trace("repeat_till0", move |mut i: I| { let mut res = C::initial(None); loop { let len = i.eof_offset(); @@ -187,7 +272,10 @@ where Ok((i1, o)) => { // infinite loop check: the parser must always consume if i1.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); + return Err(ErrMode::assert( + i, + "`repeat` parsers must always consume", + )); } res.accumulate(o); @@ -201,7 +289,7 @@ where }) } -/// Alternates between two parsers to produce a list of elements. +/// [`Accumulate`] the output of a parser, interleaed with `sep` /// /// This stops when either parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see /// [`cut_err`][crate::combinator::cut_err]. @@ -212,12 +300,12 @@ where /// /// # Example /// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] +/// ```rust +/// # #[cfg(feature = "std")] { /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::separated0; -/// use winnow::bytes::tag; +/// use winnow::combinator::separated0; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// separated0("abc", "|").parse_next(s) @@ -228,6 +316,7 @@ where /// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("def|abc"), Ok(("def|abc", vec![]))); +/// # } /// ``` #[doc(alias = "sep_by")] #[doc(alias = "separated_list0")] @@ -276,7 +365,7 @@ where }) } -/// Alternates between two parsers to produce a list of elements until [`ErrMode::Backtrack`]. +/// [`Accumulate`] the output of a parser, interleaed with `sep` /// /// Fails if the element parser does not produce at least one element.$ /// @@ -289,12 +378,12 @@ where /// /// # Example /// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] +/// ```rust +/// # #[cfg(feature = "std")] { /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::separated1; -/// use winnow::bytes::tag; +/// use winnow::combinator::separated1; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// separated1("abc", "|").parse_next(s) @@ -305,6 +394,7 @@ where /// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); /// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("def|abc"), Err(ErrMode::Backtrack(Error::new("def|abc", ErrorKind::Tag)))); +/// # } /// ``` #[doc(alias = "sep_by1")] #[doc(alias = "separated_list1")] @@ -363,8 +453,8 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::separated_foldl1; -/// use winnow::character::dec_int; +/// use winnow::combinator::separated_foldl1; +/// use winnow::ascii::dec_int; /// /// fn parser(s: &str) -> IResult<&str, i32> { /// separated_foldl1(dec_int, "-", |l, _, r| l - r).parse_next(s) @@ -397,7 +487,7 @@ where Ok((i1, s)) => { // infinite loop check: the parser must always consume if i1.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); + return Err(ErrMode::assert(i, "`repeat` parsers must always consume")); } match parser.parse_next(i1.clone()) { @@ -424,8 +514,8 @@ where /// ``` /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::separated_foldr1; -/// use winnow::character::dec_uint; +/// use winnow::combinator::separated_foldr1; +/// use winnow::ascii::dec_uint; /// /// fn parser(s: &str) -> IResult<&str, u32> { /// separated_foldr1(dec_uint, "^", |l: u32, _, r: u32| l.pow(r)).parse_next(s) @@ -452,7 +542,7 @@ where trace("separated_foldr1", move |i: I| { let (i, ol) = parser.parse_next(i)?; let (i, all): (_, crate::lib::std::vec::Vec<(O2, O)>) = - many0((sep.by_ref(), parser.by_ref())).parse_next(i)?; + repeat(0.., (sep.by_ref(), parser.by_ref())).parse_next(i)?; if let Some((s, or)) = all .into_iter() .rev() @@ -466,141 +556,94 @@ where }) } -/// Repeats the embedded parser `m..=n` times -/// -/// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see -/// [`cut_err`][crate::combinator::cut_err]. -/// -/// # Arguments -/// * `m` The minimum number of iterations. -/// * `n` The maximum number of iterations. -/// * `f` The parser to apply. -/// -/// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. -/// -/// **Warning:** If the parser passed to `many1` accepts empty inputs -/// (like `alpha0` or `digit0`), `many1` will return an error, -/// to prevent going into an infinite loop. -/// -/// # Example -/// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; -/// # use winnow::prelude::*; -/// use winnow::multi::many_m_n; -/// use winnow::bytes::tag; -/// -/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// many_m_n(0, 2, "abc").parse_next(s) -/// } -/// -/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); -/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); -/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); -/// assert_eq!(parser(""), Ok(("", vec![]))); -/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); -/// ``` -#[doc(alias = "repeated")] -pub fn many_m_n<I, O, C, E, F>(min: usize, max: usize, mut parse: F) -> impl Parser<I, C, E> +fn repeat_m_n_<I, O, C, E, F>( + min: usize, + max: usize, + parse: &mut F, + mut input: I, +) -> IResult<I, C, E> where I: Stream, C: Accumulate<O>, F: Parser<I, O, E>, E: ParseError<I>, { - trace("many_m_n", move |mut input: I| { - if min > max { - return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); - } - - let mut res = C::initial(Some(min)); - for count in 0..max { - let len = input.eof_offset(); - match parse.parse_next(input.clone()) { - Ok((tail, value)) => { - // infinite loop check: the parser must always consume - if tail.eof_offset() == len { - return Err(ErrMode::assert(input, "many parsers must always consume")); - } - - res.accumulate(value); - input = tail; - } - Err(ErrMode::Backtrack(e)) => { - if count < min { - return Err(ErrMode::Backtrack(e.append(input, ErrorKind::Many))); - } else { - return Ok((input, res)); - } + if min > max { + return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); + } + + let mut res = C::initial(Some(min)); + for count in 0..max { + let len = input.eof_offset(); + match parse.parse_next(input.clone()) { + Ok((tail, value)) => { + // infinite loop check: the parser must always consume + if tail.eof_offset() == len { + return Err(ErrMode::assert( + input, + "`repeat` parsers must always consume", + )); } - Err(e) => { - return Err(e); + + res.accumulate(value); + input = tail; + } + Err(ErrMode::Backtrack(e)) => { + if count < min { + return Err(ErrMode::Backtrack(e.append(input, ErrorKind::Many))); + } else { + return Ok((input, res)); } } + Err(e) => { + return Err(e); + } } + } - Ok((input, res)) - }) + Ok((input, res)) } -/// [`Accumulate`] the output of a parser into a container, like `Vec` -/// -/// # Arguments -/// * `f` The parser to apply. -/// * `count` How often to apply the parser. -/// -/// To recognize a series of tokens, [`Accumulate`] into a `()` and then [`Parser::recognize`]. -/// -/// # Example -/// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; -/// # use winnow::prelude::*; -/// use winnow::multi::count; -/// use winnow::bytes::tag; -/// -/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// count("abc", 2).parse_next(s) -/// } -/// -/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); -/// assert_eq!(parser("abc123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); -/// assert_eq!(parser("123123"), Err(ErrMode::Backtrack(Error::new("123123", ErrorKind::Tag)))); -/// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); -/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); -/// ``` -#[doc(alias = "skip_counskip_count")] -pub fn count<I, O, C, E, F>(mut f: F, count: usize) -> impl Parser<I, C, E> +/// Deprecated, replaced by [`repeat`] +#[deprecated(since = "0.4.6", note = "Replaced with `repeat`")] +#[inline(always)] +pub fn count<I, O, C, E, F>(f: F, count: usize) -> impl Parser<I, C, E> where I: Stream, C: Accumulate<O>, F: Parser<I, O, E>, E: ParseError<I>, { - trace("count", move |i: I| { - let mut input = i.clone(); - let mut res = C::initial(Some(count)); + repeat(count, f) +} - for _ in 0..count { - let input_ = input.clone(); - match f.parse_next(input_) { - Ok((i, o)) => { - res.accumulate(o); - input = i; - } - Err(e) => { - return Err(e.append(i, ErrorKind::Many)); - } +fn repeat_n_<I, O, C, E, F>(count: usize, f: &mut F, i: I) -> IResult<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + let mut input = i.clone(); + let mut res = C::initial(Some(count)); + + for _ in 0..count { + let input_ = input.clone(); + match f.parse_next(input_) { + Ok((i, o)) => { + res.accumulate(o); + input = i; + } + Err(e) => { + return Err(e.append(i, ErrorKind::Many)); } } + } - Ok((input, res)) - }) + Ok((input, res)) } -/// Runs the embedded parser repeatedly, filling the given slice with results. +/// Repeats the embedded parser, filling the given slice with results. /// /// This parser fails if the input runs out before the given slice is full. /// @@ -613,8 +656,8 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::fill; -/// use winnow::bytes::tag; +/// use winnow::combinator::fill; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, [&str; 2]> { /// let mut buf = ["", ""]; @@ -654,30 +697,35 @@ where }) } -/// Repeats the embedded parser, calling `g` to gather the results. +/// Repeats the embedded parser `m..=n` times, calling `g` to gather the results /// -/// This stops on [`ErrMode::Backtrack`]. To instead chain an error up, see +/// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see /// [`cut_err`][crate::combinator::cut_err]. /// /// # Arguments +/// * `m` The minimum number of iterations. +/// * `n` The maximum number of iterations. /// * `f` The parser to apply. /// * `init` A function returning the initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. /// -/// **Warning:** if the parser passed in accepts empty inputs (like `alpha0` or `digit0`), `many0` will -/// return an error, to prevent going into an infinite loop +/// **Warning:** If the parser passed to `fold_repeat` accepts empty inputs +/// (like `alpha0` or `digit0`), `fold_repeat` will return an error, +/// to prevent going into an infinite loop. /// /// # Example /// +/// Zero or more repetitions: /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::fold_many0; -/// use winnow::bytes::tag; +/// use winnow::combinator::fold_repeat; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// fold_many0( +/// fold_repeat( +/// 0.., /// "abc", /// Vec::new, /// |mut acc: Vec<_>, item| { @@ -692,67 +740,17 @@ where /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// ``` -pub fn fold_many0<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> -where - I: Stream, - F: Parser<I, O, E>, - G: FnMut(R, O) -> R, - H: FnMut() -> R, - E: ParseError<I>, -{ - trace("fold_many0", move |i: I| { - let mut res = init(); - let mut input = i; - - loop { - let i_ = input.clone(); - let len = input.eof_offset(); - match f.parse_next(i_) { - Ok((i, o)) => { - // infinite loop check: the parser must always consume - if i.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); - } - - res = g(res, o); - input = i; - } - Err(ErrMode::Backtrack(_)) => { - return Ok((input, res)); - } - Err(e) => { - return Err(e); - } - } - } - }) -} - -/// Repeats the embedded parser, calling `g` to gather the results. -/// -/// This stops on [`ErrMode::Backtrack`] if there is at least one result. To instead chain an error up, -/// see [`cut_err`][crate::combinator::cut_err]. -/// -/// # Arguments -/// * `f` The parser to apply. -/// * `init` A function returning the initial value. -/// * `g` The function that combines a result of `f` with -/// the current accumulator. -/// -/// **Warning:** If the parser passed to `many1` accepts empty inputs -/// (like `alpha0` or `digit0`), `many1` will return an error, -/// to prevent going into an infinite loop. -/// -/// # Example /// +/// One or more repetitions: /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::fold_many1; -/// use winnow::bytes::tag; +/// use winnow::combinator::fold_repeat; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// fold_many1( +/// fold_repeat( +/// 1.., /// "abc", /// Vec::new, /// |mut acc: Vec<_>, item| { @@ -767,79 +765,17 @@ where /// assert_eq!(parser("123123"), Err(ErrMode::Backtrack(Error::new("123123", ErrorKind::Many)))); /// assert_eq!(parser(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Many)))); /// ``` -pub fn fold_many1<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> -where - I: Stream, - F: Parser<I, O, E>, - G: FnMut(R, O) -> R, - H: FnMut() -> R, - E: ParseError<I>, -{ - trace("fold_many1", move |i: I| { - let _i = i.clone(); - let init = init(); - match f.parse_next(_i) { - Err(ErrMode::Backtrack(_)) => Err(ErrMode::from_error_kind(i, ErrorKind::Many)), - Err(e) => Err(e), - Ok((i1, o1)) => { - let mut acc = g(init, o1); - let mut input = i1; - - loop { - let _input = input.clone(); - let len = input.eof_offset(); - match f.parse_next(_input) { - Err(ErrMode::Backtrack(_)) => { - break; - } - Err(e) => return Err(e), - Ok((i, o)) => { - // infinite loop check: the parser must always consume - if i.eof_offset() == len { - return Err(ErrMode::assert(i, "many parsers must always consume")); - } - - acc = g(acc, o); - input = i; - } - } - } - - Ok((input, acc)) - } - } - }) -} - -/// Repeats the embedded parser `m..=n` times, calling `g` to gather the results -/// -/// This stops before `n` when the parser returns [`ErrMode::Backtrack`]. To instead chain an error up, see -/// [`cut_err`][crate::combinator::cut_err]. -/// -/// # Arguments -/// * `m` The minimum number of iterations. -/// * `n` The maximum number of iterations. -/// * `f` The parser to apply. -/// * `init` A function returning the initial value. -/// * `g` The function that combines a result of `f` with -/// the current accumulator. -/// -/// **Warning:** If the parser passed to `many1` accepts empty inputs -/// (like `alpha0` or `digit0`), `many1` will return an error, -/// to prevent going into an infinite loop. -/// -/// # Example /// +/// Arbitrary number of repetitions: /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::multi::fold_many_m_n; -/// use winnow::bytes::tag; +/// use winnow::combinator::fold_repeat; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// fold_many_m_n( -/// 0, -/// 2, +/// fold_repeat( +/// 0..=2, /// "abc", /// Vec::new, /// |mut acc: Vec<_>, item| { @@ -855,12 +791,15 @@ where /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` -pub fn fold_many_m_n<I, O, E, F, G, H, R>( - min: usize, - max: usize, - mut parse: F, +#[doc(alias = "fold_many0")] +#[doc(alias = "fold_many1")] +#[doc(alias = "fold_many_m_n")] +#[inline(always)] +pub fn fold_repeat<I, O, E, F, G, H, R>( + range: impl Into<Range>, + mut f: F, mut init: H, - mut fold: G, + mut g: G, ) -> impl Parser<I, R, E> where I: Stream, @@ -869,197 +808,180 @@ where H: FnMut() -> R, E: ParseError<I>, { - trace("fold_many_m_n", move |mut input: I| { - if min > max { - return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); + let Range { + start_inclusive, + end_inclusive, + } = range.into(); + trace("fold_repeat", move |i: I| { + match (start_inclusive, end_inclusive) { + (0, None) => fold_repeat0_(&mut f, &mut init, &mut g, i), + (1, None) => fold_repeat1_(&mut f, &mut init, &mut g, i), + (start, end) => fold_repeat_m_n_( + start, + end.unwrap_or(usize::MAX), + &mut f, + &mut init, + &mut g, + i, + ), } + }) +} - let mut acc = init(); - for count in 0..max { - let len = input.eof_offset(); - match parse.parse_next(input.clone()) { - Ok((tail, value)) => { - // infinite loop check: the parser must always consume - if tail.eof_offset() == len { - return Err(ErrMode::assert(input, "many parsers must always consume")); - } +/// Deprecated, replaced by [`fold_repeat`] +#[deprecated(since = "0.4.6", note = "Replaced with `fold_repeat`")] +#[inline(always)] +pub fn fold_repeat0<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> +where + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, + E: ParseError<I>, +{ + trace("fold_repeat0", move |i: I| { + fold_repeat0_(&mut f, &mut init, &mut g, i) + }) +} - acc = fold(acc, value); - input = tail; - } - //FInputXMError: handle failure properly - Err(ErrMode::Backtrack(err)) => { - if count < min { - return Err(ErrMode::Backtrack(err.append(input, ErrorKind::Many))); - } else { - break; - } +fn fold_repeat0_<I, O, E, F, G, H, R>(f: &mut F, init: &mut H, g: &mut G, i: I) -> IResult<I, R, E> +where + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, + E: ParseError<I>, +{ + let mut res = init(); + let mut input = i; + + loop { + let i_ = input.clone(); + let len = input.eof_offset(); + match f.parse_next(i_) { + Ok((i, o)) => { + // infinite loop check: the parser must always consume + if i.eof_offset() == len { + return Err(ErrMode::assert(i, "`repeat` parsers must always consume")); } - Err(e) => return Err(e), + + res = g(res, o); + input = i; + } + Err(ErrMode::Backtrack(_)) => { + return Ok((input, res)); + } + Err(e) => { + return Err(e); } } - - Ok((input, acc)) - }) + } } -/// Gets a number from the parser and returns a -/// subslice of the input of that size. -/// -/// *Complete version*: Returns an error if there is not enough input data. -/// -/// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data. -/// -/// # Arguments -/// * `f` The parser to apply. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed, stream::Partial}; -/// # use winnow::prelude::*; -/// use winnow::Bytes; -/// use winnow::number::be_u16; -/// use winnow::multi::length_data; -/// use winnow::bytes::tag; -/// -/// type Stream<'i> = Partial<&'i Bytes>; -/// -/// fn stream(b: &[u8]) -> Stream<'_> { -/// Partial::new(Bytes::new(b)) -/// } -/// -/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> { -/// length_data(be_u16).parse_next(s) -/// } -/// -/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..]))); -/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2)))); -/// ``` -pub fn length_data<I, N, E, F>(mut f: F) -> impl Parser<I, <I as Stream>::Slice, E> +/// Deprecated, replaced by [`fold_repeat`] +#[deprecated(since = "0.4.6", note = "Replaced with `fold_repeat`")] +#[inline(always)] +pub fn fold_repeat1<I, O, E, F, G, H, R>(mut f: F, mut init: H, mut g: G) -> impl Parser<I, R, E> where - I: StreamIsPartial, I: Stream, - N: ToUsize, - F: Parser<I, N, E>, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, E: ParseError<I>, { - trace("length_data", move |i: I| { - let (i, length) = f.parse_next(i)?; - - crate::bytes::take(length).parse_next(i) + trace("fold_repeat1", move |i: I| { + fold_repeat1_(&mut f, &mut init, &mut g, i) }) } -/// Gets a number from the first parser, -/// takes a subslice of the input of that size, -/// then applies the second parser on that subslice. -/// If the second parser returns `Incomplete`, -/// `length_value` will return an error. -/// -/// *Complete version*: Returns an error if there is not enough input data. -/// -/// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data. -/// -/// # Arguments -/// * `f` The parser to apply. -/// * `g` The parser to apply on the subslice. -/// -/// # Example -/// -/// ```rust -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed, stream::{Partial, StreamIsPartial}}; -/// # use winnow::prelude::*; -/// use winnow::Bytes; -/// use winnow::number::be_u16; -/// use winnow::multi::length_value; -/// use winnow::bytes::tag; -/// -/// type Stream<'i> = Partial<&'i Bytes>; -/// -/// fn stream(b: &[u8]) -> Stream<'_> { -/// Partial::new(Bytes::new(b)) -/// } -/// -/// fn complete_stream(b: &[u8]) -> Stream<'_> { -/// let mut p = Partial::new(Bytes::new(b)); -/// let _ = p.complete(); -/// p -/// } -/// -/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> { -/// length_value(be_u16, "abc").parse_next(s) -/// } -/// -/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..]))); -/// assert_eq!(parser(stream(b"\x00\x03123123")), Err(ErrMode::Backtrack(Error::new(complete_stream(&b"123"[..]), ErrorKind::Tag)))); -/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2)))); -/// ``` -pub fn length_value<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, O, E> +fn fold_repeat1_<I, O, E, F, G, H, R>(f: &mut F, init: &mut H, g: &mut G, i: I) -> IResult<I, R, E> where - I: StreamIsPartial, - I: Stream + UpdateSlice, - N: ToUsize, - F: Parser<I, N, E>, - G: Parser<I, O, E>, + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, E: ParseError<I>, { - trace("length_value", move |i: I| { - let (i, data) = length_data(f.by_ref()).parse_next(i)?; - let mut data = I::update_slice(i.clone(), data); - let _ = data.complete(); - let (_, o) = g.by_ref().complete_err().parse_next(data)?; - Ok((i, o)) - }) + let _i = i.clone(); + let init = init(); + match f.parse_next(_i) { + Err(ErrMode::Backtrack(_)) => Err(ErrMode::from_error_kind(i, ErrorKind::Many)), + Err(e) => Err(e), + Ok((i1, o1)) => { + let mut acc = g(init, o1); + let mut input = i1; + + loop { + let _input = input.clone(); + let len = input.eof_offset(); + match f.parse_next(_input) { + Err(ErrMode::Backtrack(_)) => { + break; + } + Err(e) => return Err(e), + Ok((i, o)) => { + // infinite loop check: the parser must always consume + if i.eof_offset() == len { + return Err(ErrMode::assert(i, "`repeat` parsers must always consume")); + } + + acc = g(acc, o); + input = i; + } + } + } + + Ok((input, acc)) + } + } } -/// Gets a number from the first parser, -/// then applies the second parser that many times. -/// -/// # Arguments -/// * `f` The parser to apply to obtain the count. -/// * `g` The parser to apply repeatedly. -/// -/// # Example -/// -#[cfg_attr(not(feature = "std"), doc = "```ignore")] -#[cfg_attr(feature = "std", doc = "```")] -/// # use winnow::prelude::*; -/// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; -/// # use winnow::prelude::*; -/// use winnow::Bytes; -/// use winnow::number::u8; -/// use winnow::multi::length_count; -/// use winnow::bytes::tag; -/// -/// type Stream<'i> = &'i Bytes; -/// -/// fn stream(b: &[u8]) -> Stream<'_> { -/// Bytes::new(b) -/// } -/// -/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, Vec<&[u8]>> { -/// length_count(u8.map(|i| { -/// println!("got number: {}", i); -/// i -/// }), "abc").parse_next(s) -/// } -/// -/// assert_eq!(parser(stream(b"\x02abcabcabc")), Ok((stream(b"abc"), vec![&b"abc"[..], &b"abc"[..]]))); -/// assert_eq!(parser(stream(b"\x03123123123")), Err(ErrMode::Backtrack(Error::new(stream(b"123123123"), ErrorKind::Tag)))); -/// ``` -pub fn length_count<I, O, C, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, C, E> +fn fold_repeat_m_n_<I, O, E, F, G, H, R>( + min: usize, + max: usize, + parse: &mut F, + init: &mut H, + fold: &mut G, + mut input: I, +) -> IResult<I, R, E> where I: Stream, - N: ToUsize, - C: Accumulate<O>, - F: Parser<I, N, E>, - G: Parser<I, O, E>, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, E: ParseError<I>, { - trace("length_count", move |i: I| { - let (i, n) = f.parse_next(i)?; - let n = n.to_usize(); - count(g.by_ref(), n).parse_next(i) - }) + if min > max { + return Err(ErrMode::Cut(E::from_error_kind(input, ErrorKind::Many))); + } + + let mut acc = init(); + for count in 0..max { + let len = input.eof_offset(); + match parse.parse_next(input.clone()) { + Ok((tail, value)) => { + // infinite loop check: the parser must always consume + if tail.eof_offset() == len { + return Err(ErrMode::assert( + input, + "`repeat` parsers must always consume", + )); + } + + acc = fold(acc, value); + input = tail; + } + //FInputXMError: handle failure properly + Err(ErrMode::Backtrack(err)) => { + if count < min { + return Err(ErrMode::Backtrack(err.append(input, ErrorKind::Many))); + } else { + break; + } + } + Err(e) => return Err(e), + } + } + + Ok((input, acc)) } diff --git a/vendor/winnow/src/combinator/parser.rs b/vendor/winnow/src/combinator/parser.rs new file mode 100644 index 000000000..12b223a2e --- /dev/null +++ b/vendor/winnow/src/combinator/parser.rs @@ -0,0 +1,827 @@ +use crate::error::{ContextError, ErrMode, ErrorKind, FromExternalError, ParseError}; +use crate::lib::std::borrow::Borrow; +use crate::lib::std::ops::Range; +use crate::stream::{Location, Stream}; +use crate::stream::{Offset, StreamIsPartial}; +use crate::trace::trace; +use crate::trace::trace_result; +use crate::*; + +/// Implementation of [`Parser::by_ref`][Parser::by_ref] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct ByRef<'p, P> { + p: &'p mut P, +} + +impl<'p, P> ByRef<'p, P> { + pub(crate) fn new(p: &'p mut P) -> Self { + Self { p } + } +} + +impl<'p, I, O, E, P: Parser<I, O, E>> Parser<I, O, E> for ByRef<'p, P> { + fn parse_next(&mut self, i: I) -> IResult<I, O, E> { + self.p.parse_next(i) + } +} + +/// Implementation of [`Parser::map`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Map<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(O) -> O2, +{ + parser: F, + map: G, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, G, I, O, O2, E> Map<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(O) -> O2, +{ + pub(crate) fn new(parser: F, map: G) -> Self { + Self { + parser, + map, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, G, I, O, O2, E> Parser<I, O2, E> for Map<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(O) -> O2, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { + match self.parser.parse_next(i) { + Err(e) => Err(e), + Ok((i, o)) => Ok((i, (self.map)(o))), + } + } +} + +#[deprecated(since = "0.4.2", note = "Replaced with `TryMap`")] +pub use TryMap as MapRes; + +/// Implementation of [`Parser::try_map`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct TryMap<F, G, I, O, O2, E, E2> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Result<O2, E2>, + I: Clone, + E: FromExternalError<I, E2>, +{ + parser: F, + map: G, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, + e2: core::marker::PhantomData<E2>, +} + +impl<F, G, I, O, O2, E, E2> TryMap<F, G, I, O, O2, E, E2> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Result<O2, E2>, + I: Clone, + E: FromExternalError<I, E2>, +{ + pub(crate) fn new(parser: F, map: G) -> Self { + Self { + parser, + map, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + e2: Default::default(), + } + } +} + +impl<F, G, I, O, O2, E, E2> Parser<I, O2, E> for TryMap<F, G, I, O, O2, E, E2> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Result<O2, E2>, + I: Clone, + E: FromExternalError<I, E2>, +{ + fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { + let i = input.clone(); + let (input, o) = self.parser.parse_next(input)?; + let res = match (self.map)(o) { + Ok(o2) => Ok((input, o2)), + Err(e) => Err(ErrMode::from_external_error(i, ErrorKind::Verify, e)), + }; + trace_result("verify", &res); + res + } +} + +/// Implementation of [`Parser::verify_map`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct VerifyMap<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Option<O2>, + I: Clone, + E: ParseError<I>, +{ + parser: F, + map: G, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, G, I, O, O2, E> VerifyMap<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Option<O2>, + I: Clone, + E: ParseError<I>, +{ + pub(crate) fn new(parser: F, map: G) -> Self { + Self { + parser, + map, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, G, I, O, O2, E> Parser<I, O2, E> for VerifyMap<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> Option<O2>, + I: Clone, + E: ParseError<I>, +{ + fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { + let i = input.clone(); + let (input, o) = self.parser.parse_next(input)?; + let res = match (self.map)(o) { + Some(o2) => Ok((input, o2)), + None => Err(ErrMode::from_error_kind(i, ErrorKind::Verify)), + }; + trace_result("verify", &res); + res + } +} + +/// Implementation of [`Parser::and_then`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct AndThen<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Parser<O, O2, E>, + O: StreamIsPartial, +{ + outer: F, + inner: G, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, G, I, O, O2, E> AndThen<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Parser<O, O2, E>, + O: StreamIsPartial, +{ + pub(crate) fn new(outer: F, inner: G) -> Self { + Self { + outer, + inner, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, G, I, O, O2, E> Parser<I, O2, E> for AndThen<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Parser<O, O2, E>, + O: StreamIsPartial, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { + let (i, mut o) = self.outer.parse_next(i)?; + let _ = o.complete(); + let (_, o2) = self.inner.parse_next(o)?; + Ok((i, o2)) + } +} + +/// Implementation of [`Parser::parse_to`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct ParseTo<P, I, O, O2, E> +where + P: Parser<I, O, E>, + I: Stream, + O: crate::stream::ParseSlice<O2>, + E: ParseError<I>, +{ + p: P, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<P, I, O, O2, E> ParseTo<P, I, O, O2, E> +where + P: Parser<I, O, E>, + I: Stream, + O: crate::stream::ParseSlice<O2>, + E: ParseError<I>, +{ + pub(crate) fn new(p: P) -> Self { + Self { + p, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<P, I, O, O2, E> Parser<I, O2, E> for ParseTo<P, I, O, O2, E> +where + P: Parser<I, O, E>, + I: Stream, + O: crate::stream::ParseSlice<O2>, + E: ParseError<I>, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { + let input = i.clone(); + let (i, o) = self.p.parse_next(i)?; + + let res = o + .parse_slice() + .ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Verify)); + trace_result("verify", &res); + Ok((i, res?)) + } +} + +/// Implementation of [`Parser::flat_map`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct FlatMap<F, G, H, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> H, + H: Parser<I, O2, E>, +{ + f: F, + g: G, + h: core::marker::PhantomData<H>, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, G, H, I, O, O2, E> FlatMap<F, G, H, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> H, + H: Parser<I, O2, E>, +{ + pub(crate) fn new(f: F, g: G) -> Self { + Self { + f, + g, + h: Default::default(), + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, G, H, I, O, O2, E> Parser<I, O2, E> for FlatMap<F, G, H, I, O, O2, E> +where + F: Parser<I, O, E>, + G: FnMut(O) -> H, + H: Parser<I, O2, E>, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { + let (i, o) = self.f.parse_next(i)?; + (self.g)(o).parse_next(i) + } +} + +/// Implementation of [`Parser::complete_err`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct CompleteErr<F> { + f: F, +} + +impl<F> CompleteErr<F> { + pub(crate) fn new(f: F) -> Self { + Self { f } + } +} + +impl<F, I, O, E> Parser<I, O, E> for CompleteErr<F> +where + I: Stream, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + fn parse_next(&mut self, input: I) -> IResult<I, O, E> { + trace("complete_err", |input: I| { + let i = input.clone(); + match (self.f).parse_next(input) { + Err(ErrMode::Incomplete(_)) => { + Err(ErrMode::from_error_kind(i, ErrorKind::Complete)) + } + rest => rest, + } + }) + .parse_next(input) + } +} + +/// Implementation of [`Parser::verify`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Verify<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(&O2) -> bool, + I: Clone, + O: Borrow<O2>, + O2: ?Sized, + E: ParseError<I>, +{ + parser: F, + filter: G, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, G, I, O, O2, E> Verify<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(&O2) -> bool, + I: Clone, + O: Borrow<O2>, + O2: ?Sized, + E: ParseError<I>, +{ + pub(crate) fn new(parser: F, filter: G) -> Self { + Self { + parser, + filter, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, G, I, O, O2, E> Parser<I, O, E> for Verify<F, G, I, O, O2, E> +where + F: Parser<I, O, E>, + G: Fn(&O2) -> bool, + I: Clone, + O: Borrow<O2>, + O2: ?Sized, + E: ParseError<I>, +{ + fn parse_next(&mut self, input: I) -> IResult<I, O, E> { + let i = input.clone(); + let (input, o) = self.parser.parse_next(input)?; + + let res = if (self.filter)(o.borrow()) { + Ok((input, o)) + } else { + Err(ErrMode::from_error_kind(i, ErrorKind::Verify)) + }; + trace_result("verify", &res); + res + } +} + +/// Implementation of [`Parser::value`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Value<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O2: Clone, +{ + parser: F, + val: O2, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, O2, E> Value<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O2: Clone, +{ + pub(crate) fn new(parser: F, val: O2) -> Self { + Self { + parser, + val, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, O2, E> Parser<I, O2, E> for Value<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O2: Clone, +{ + fn parse_next(&mut self, input: I) -> IResult<I, O2, E> { + (self.parser) + .parse_next(input) + .map(|(i, _)| (i, self.val.clone())) + } +} + +/// Implementation of [`Parser::void`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Void<F, I, O, E> +where + F: Parser<I, O, E>, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E> Void<F, I, O, E> +where + F: Parser<I, O, E>, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, E> Parser<I, (), E> for Void<F, I, O, E> +where + F: Parser<I, O, E>, +{ + fn parse_next(&mut self, input: I) -> IResult<I, (), E> { + (self.parser).parse_next(input).map(|(i, _)| (i, ())) + } +} + +/// Implementation of [`Parser::recognize`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Recognize<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E> Recognize<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<I, O, E, F> Parser<I, <I as Stream>::Slice, E> for Recognize<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + fn parse_next(&mut self, input: I) -> IResult<I, <I as Stream>::Slice, E> { + let i = input.clone(); + match (self.parser).parse_next(i) { + Ok((i, _)) => { + let offset = input.offset_to(&i); + Ok(input.next_slice(offset)) + } + Err(e) => Err(e), + } + } +} + +/// Implementation of [`Parser::with_recognized`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct WithRecognized<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E> WithRecognized<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, E> Parser<I, (O, <I as Stream>::Slice), E> for WithRecognized<F, I, O, E> +where + F: Parser<I, O, E>, + I: Stream + Offset, +{ + fn parse_next(&mut self, input: I) -> IResult<I, (O, <I as Stream>::Slice), E> { + let i = input.clone(); + match (self.parser).parse_next(i) { + Ok((remaining, result)) => { + let offset = input.offset_to(&remaining); + let (remaining, recognized) = input.next_slice(offset); + Ok((remaining, (result, recognized))) + } + Err(e) => Err(e), + } + } +} + +/// Implementation of [`Parser::span`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Span<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E> Span<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<I, O, E, F> Parser<I, Range<usize>, E> for Span<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + fn parse_next(&mut self, input: I) -> IResult<I, Range<usize>, E> { + let start = input.location(); + self.parser.parse_next(input).map(move |(remaining, _)| { + let end = remaining.location(); + (remaining, (start..end)) + }) + } +} + +/// Implementation of [`Parser::with_span`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct WithSpan<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E> WithSpan<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, E> Parser<I, (O, Range<usize>), E> for WithSpan<F, I, O, E> +where + F: Parser<I, O, E>, + I: Clone + Location, +{ + fn parse_next(&mut self, input: I) -> IResult<I, (O, Range<usize>), E> { + let start = input.location(); + self.parser + .parse_next(input) + .map(move |(remaining, output)| { + let end = remaining.location(); + (remaining, (output, (start..end))) + }) + } +} + +/// Implementation of [`Parser::output_into`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct OutputInto<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O: Into<O2>, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + o2: core::marker::PhantomData<O2>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, O2, E> OutputInto<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O: Into<O2>, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + o2: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, O2, E> Parser<I, O2, E> for OutputInto<F, I, O, O2, E> +where + F: Parser<I, O, E>, + O: Into<O2>, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O2, E> { + match self.parser.parse_next(i) { + Ok((i, o)) => Ok((i, o.into())), + Err(err) => Err(err), + } + } +} + +/// Implementation of [`Parser::err_into`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct ErrInto<F, I, O, E, E2> +where + F: Parser<I, O, E>, + E: Into<E2>, +{ + parser: F, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, + e2: core::marker::PhantomData<E2>, +} + +impl<F, I, O, E, E2> ErrInto<F, I, O, E, E2> +where + F: Parser<I, O, E>, + E: Into<E2>, +{ + pub(crate) fn new(parser: F) -> Self { + Self { + parser, + i: Default::default(), + o: Default::default(), + e: Default::default(), + e2: Default::default(), + } + } +} + +impl<F, I, O, E, E2> Parser<I, O, E2> for ErrInto<F, I, O, E, E2> +where + F: Parser<I, O, E>, + E: Into<E2>, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O, E2> { + match self.parser.parse_next(i) { + Ok(ok) => Ok(ok), + Err(ErrMode::Backtrack(e)) => Err(ErrMode::Backtrack(e.into())), + Err(ErrMode::Cut(e)) => Err(ErrMode::Cut(e.into())), + Err(ErrMode::Incomplete(e)) => Err(ErrMode::Incomplete(e)), + } + } +} + +/// Implementation of [`Parser::context`] +#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))] +pub struct Context<F, I, O, E, C> +where + F: Parser<I, O, E>, + I: Stream, + E: ContextError<I, C>, + C: Clone + crate::lib::std::fmt::Debug, +{ + parser: F, + context: C, + i: core::marker::PhantomData<I>, + o: core::marker::PhantomData<O>, + e: core::marker::PhantomData<E>, +} + +impl<F, I, O, E, C> Context<F, I, O, E, C> +where + F: Parser<I, O, E>, + I: Stream, + E: ContextError<I, C>, + C: Clone + crate::lib::std::fmt::Debug, +{ + pub(crate) fn new(parser: F, context: C) -> Self { + Self { + parser, + context, + i: Default::default(), + o: Default::default(), + e: Default::default(), + } + } +} + +impl<F, I, O, E, C> Parser<I, O, E> for Context<F, I, O, E, C> +where + F: Parser<I, O, E>, + I: Stream, + E: ContextError<I, C>, + C: Clone + crate::lib::std::fmt::Debug, +{ + fn parse_next(&mut self, i: I) -> IResult<I, O, E> { + #[cfg(feature = "debug")] + let name = format!("context={:?}", self.context); + #[cfg(not(feature = "debug"))] + let name = "context"; + trace(name, move |i: I| { + (self.parser) + .parse_next(i.clone()) + .map_err(|err| err.map(|err| err.add_context(i, self.context.clone()))) + }) + .parse_next(i) + } +} diff --git a/vendor/winnow/src/sequence/mod.rs b/vendor/winnow/src/combinator/sequence.rs index 68f772384..89c29a548 100644 --- a/vendor/winnow/src/sequence/mod.rs +++ b/vendor/winnow/src/combinator/sequence.rs @@ -1,14 +1,9 @@ -//! Combinators applying parsers in sequence - -#[cfg(test)] -mod tests; - use crate::error::ParseError; use crate::stream::Stream; use crate::trace::trace; -use crate::Parser; +use crate::*; -/// Apply two parsers, only returning the output from the second. +/// Sequence two parsers, only returning the output from the second. /// /// # Arguments /// * `first` The opening parser. @@ -20,8 +15,8 @@ use crate::Parser; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::sequence::preceded; -/// use winnow::bytes::tag; +/// use winnow::combinator::preceded; +/// use winnow::token::tag; /// /// let mut parser = preceded("abc", "efg"); /// @@ -46,7 +41,7 @@ where }) } -/// Apply two parsers, only returning the output of the first. +/// Sequence two parsers, only returning the output of the first. /// /// # Arguments /// * `first` The first parser to apply. @@ -58,8 +53,8 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; -/// use winnow::sequence::terminated; -/// use winnow::bytes::tag; +/// use winnow::combinator::terminated; +/// use winnow::token::tag; /// /// let mut parser = terminated("abc", "efg"); /// @@ -84,7 +79,7 @@ where }) } -/// Apply three parsers, only returning the values of the first and third. +/// Sequence three parsers, only returning the values of the first and third. /// /// # Arguments /// * `first` The first parser to apply. @@ -97,8 +92,8 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; -/// use winnow::sequence::separated_pair; -/// use winnow::bytes::tag; +/// use winnow::combinator::separated_pair; +/// use winnow::token::tag; /// /// let mut parser = separated_pair("abc", "|", "efg"); /// @@ -125,7 +120,7 @@ where }) } -/// Apply three parsers, only returning the output of the second. +/// Sequence three parsers, only returning the output of the second. /// /// # Arguments /// * `first` The first parser to apply and discard. @@ -138,8 +133,8 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; -/// use winnow::sequence::delimited; -/// use winnow::bytes::tag; +/// use winnow::combinator::delimited; +/// use winnow::token::tag; /// /// let mut parser = delimited("(", "abc", ")"); /// diff --git a/vendor/winnow/src/combinator/tests.rs b/vendor/winnow/src/combinator/tests.rs index 4286286ae..cdb787760 100644 --- a/vendor/winnow/src/combinator/tests.rs +++ b/vendor/winnow/src/combinator/tests.rs @@ -1,19 +1,22 @@ use super::*; -use crate::bytes::take; +use crate::ascii::digit1 as digit; +use crate::binary::u16; +use crate::binary::u8; +use crate::binary::Endianness; use crate::error::ErrMode; use crate::error::Error; use crate::error::ErrorKind; use crate::error::Needed; use crate::error::ParseError; -use crate::multi::count; -use crate::number::u16; -use crate::number::u8; -use crate::number::Endianness; +use crate::token::take; use crate::IResult; use crate::Parser; use crate::Partial; +#[cfg(feature = "alloc")] +use crate::lib::std::vec::Vec; + macro_rules! assert_parse( ($left: expr, $right: expr) => { let res: $crate::IResult<_, _, Error<_>> = $left; @@ -98,7 +101,7 @@ struct CustomError; #[allow(dead_code)] fn custom_error(input: &[u8]) -> IResult<&[u8], &[u8], CustomError> { //fix_error!(input, CustomError<_>, alphanumeric) - crate::character::alphanumeric1(input) + crate::ascii::alphanumeric1(input) } #[test] @@ -112,7 +115,7 @@ fn test_parser_flat_map() { #[allow(dead_code)] fn test_closure_compiles_195(input: &[u8]) -> IResult<&[u8], ()> { - u8.flat_map(|num| count(u16(Endianness::Big), num as usize)) + u8.flat_map(|num| repeat(num as usize, u16(Endianness::Big))) .parse_next(input) } @@ -146,8 +149,8 @@ fn test_parser_map_parser() { #[test] #[cfg(feature = "std")] fn test_parser_into() { - use crate::bytes::take; use crate::error::Error; + use crate::token::take; let mut parser = take::<_, _, Error<_>>(3u8).output_into(); let result: IResult<&[u8], Vec<u8>> = parser.parse_next(&b"abcdefg"[..]); @@ -226,7 +229,7 @@ fn not_test() { #[test] fn test_parser_verify() { - use crate::bytes::take; + use crate::token::take; fn test(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { take(5u8) @@ -253,7 +256,7 @@ fn test_parser_verify() { #[test] #[allow(unused)] fn test_parser_verify_ref() { - use crate::bytes::take; + use crate::token::take; let mut parser1 = take(3u8).verify(|s: &[u8]| s == &b"abc"[..]); @@ -270,7 +273,7 @@ fn test_parser_verify_ref() { ); fn parser2(i: &[u8]) -> IResult<&[u8], u32> { - crate::number::be_u32 + crate::binary::be_u32 .verify(|val: &u32| *val < 3) .parse_next(i) } @@ -279,7 +282,7 @@ fn test_parser_verify_ref() { #[test] #[cfg(feature = "alloc")] fn test_parser_verify_alloc() { - use crate::bytes::take; + use crate::token::take; let mut parser1 = take(3u8) .map(|s: &[u8]| s.to_vec()) .verify(|s: &[u8]| s == &b"abc"[..]); @@ -317,3 +320,948 @@ fn fail_test() { })) ); } + +#[test] +fn complete() { + fn err_test(i: &[u8]) -> IResult<&[u8], &[u8]> { + let (i, _) = "ijkl".parse_next(i)?; + "mnop".parse_next(i) + } + let a = &b"ijklmn"[..]; + + let res_a = err_test(a); + assert_eq!( + res_a, + Err(ErrMode::Backtrack(error_position!( + &b"mn"[..], + ErrorKind::Tag + ))) + ); +} + +#[test] +fn separated_pair_test() { + #[allow(clippy::type_complexity)] + fn sep_pair_abc_def(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (&[u8], &[u8])> { + separated_pair("abc", ",", "def").parse_next(i) + } + + assert_eq!( + sep_pair_abc_def(Partial::new(&b"abc,defghijkl"[..])), + Ok((Partial::new(&b"ghijkl"[..]), (&b"abc"[..], &b"def"[..]))) + ); + assert_eq!( + sep_pair_abc_def(Partial::new(&b"ab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + sep_pair_abc_def(Partial::new(&b"abc,d"[..])), + Err(ErrMode::Incomplete(Needed::new(2))) + ); + assert_eq!( + sep_pair_abc_def(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + sep_pair_abc_def(Partial::new(&b"xxx,def"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx,def"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + sep_pair_abc_def(Partial::new(&b"abc,xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); +} + +#[test] +fn preceded_test() { + fn preceded_abcd_efgh(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { + preceded("abcd", "efgh").parse_next(i) + } + + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"abcdefghijkl"[..])), + Ok((Partial::new(&b"ijkl"[..]), &b"efgh"[..])) + ); + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"ab"[..])), + Err(ErrMode::Incomplete(Needed::new(2))) + ); + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"abcde"[..])), + Err(ErrMode::Incomplete(Needed::new(3))) + ); + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"xxxxdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxxdef"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + preceded_abcd_efgh(Partial::new(&b"abcdxxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); +} + +#[test] +fn terminated_test() { + fn terminated_abcd_efgh(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { + terminated("abcd", "efgh").parse_next(i) + } + + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"abcdefghijkl"[..])), + Ok((Partial::new(&b"ijkl"[..]), &b"abcd"[..])) + ); + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"ab"[..])), + Err(ErrMode::Incomplete(Needed::new(2))) + ); + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"abcde"[..])), + Err(ErrMode::Incomplete(Needed::new(3))) + ); + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"xxxxdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxxdef"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + terminated_abcd_efgh(Partial::new(&b"abcdxxxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxx"[..]), + ErrorKind::Tag + ))) + ); +} + +#[test] +fn delimited_test() { + fn delimited_abc_def_ghi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { + delimited("abc", "def", "ghi").parse_next(i) + } + + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"abcdefghijkl"[..])), + Ok((Partial::new(&b"jkl"[..]), &b"def"[..])) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"ab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"abcde"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"abcdefgh"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"xxxdefghi"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxdefghi"[..]), + ErrorKind::Tag + ),)) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"abcxxxghi"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxghi"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + delimited_abc_def_ghi(Partial::new(&b"abcdefxxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); +} + +#[cfg(feature = "alloc")] +#[test] +fn alt_test() { + #[cfg(feature = "alloc")] + use crate::{ + error::ParseError, + lib::std::{ + fmt::Debug, + string::{String, ToString}, + }, + }; + + #[cfg(feature = "alloc")] + #[derive(Debug, Clone, Eq, PartialEq)] + pub struct ErrorStr(String); + + #[cfg(feature = "alloc")] + impl From<u32> for ErrorStr { + fn from(i: u32) -> Self { + ErrorStr(format!("custom error code: {}", i)) + } + } + + #[cfg(feature = "alloc")] + impl<'a> From<&'a str> for ErrorStr { + fn from(i: &'a str) -> Self { + ErrorStr(format!("custom error message: {}", i)) + } + } + + #[cfg(feature = "alloc")] + impl<I: Debug> ParseError<I> for ErrorStr { + fn from_error_kind(input: I, kind: ErrorKind) -> Self { + ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind)) + } + + fn append(self, input: I, kind: ErrorKind) -> Self { + ErrorStr(format!( + "custom error message: ({:?}, {:?}) - {:?}", + input, kind, self + )) + } + } + + fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + Ok((&b""[..], input)) + } + + #[allow(unused_variables)] + fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + Err(ErrMode::Backtrack(ErrorStr("abcd".to_string()))) + } + + fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + Ok((input, &b""[..])) + } + + fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + alt((dont_work, dont_work)).parse_next(i) + } + fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + alt((dont_work, work)).parse_next(i) + } + fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { + alt((dont_work, dont_work, work2, dont_work)).parse_next(i) + } + //named!(alt1, alt!(dont_work | dont_work)); + //named!(alt2, alt!(dont_work | work)); + //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work)); + + let a = &b"abcd"[..]; + assert_eq!( + alt1(a), + Err(ErrMode::Backtrack(error_node_position!( + a, + ErrorKind::Alt, + ErrorStr("abcd".to_string()) + ))) + ); + assert_eq!(alt2(a), Ok((&b""[..], a))); + assert_eq!(alt3(a), Ok((a, &b""[..]))); + + fn alt4(i: &[u8]) -> IResult<&[u8], &[u8]> { + alt(("abcd", "efgh")).parse_next(i) + } + let b = &b"efgh"[..]; + assert_eq!(alt4(a), Ok((&b""[..], a))); + assert_eq!(alt4(b), Ok((&b""[..], b))); +} + +#[test] +fn alt_incomplete() { + fn alt1(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { + alt(("a", "bc", "def")).parse_next(i) + } + + let a = &b""[..]; + assert_eq!( + alt1(Partial::new(a)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + let a = &b"b"[..]; + assert_eq!( + alt1(Partial::new(a)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + let a = &b"bcd"[..]; + assert_eq!( + alt1(Partial::new(a)), + Ok((Partial::new(&b"d"[..]), &b"bc"[..])) + ); + let a = &b"cde"[..]; + assert_eq!( + alt1(Partial::new(a)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(a), + ErrorKind::Tag + ))) + ); + let a = &b"de"[..]; + assert_eq!( + alt1(Partial::new(a)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + let a = &b"defg"[..]; + assert_eq!( + alt1(Partial::new(a)), + Ok((Partial::new(&b"g"[..]), &b"def"[..])) + ); +} + +#[test] +fn permutation_test() { + #[allow(clippy::type_complexity)] + fn perm(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (&[u8], &[u8], &[u8])> { + permutation(("abcd", "efg", "hi")).parse_next(i) + } + + let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); + + let a = &b"abcdefghijk"[..]; + assert_eq!( + perm(Partial::new(a)), + Ok((Partial::new(&b"jk"[..]), expected)) + ); + let b = &b"efgabcdhijk"[..]; + assert_eq!( + perm(Partial::new(b)), + Ok((Partial::new(&b"jk"[..]), expected)) + ); + let c = &b"hiefgabcdjk"[..]; + assert_eq!( + perm(Partial::new(c)), + Ok((Partial::new(&b"jk"[..]), expected)) + ); + + let d = &b"efgxyzabcdefghi"[..]; + assert_eq!( + perm(Partial::new(d)), + Err(ErrMode::Backtrack(error_node_position!( + Partial::new(&b"efgxyzabcdefghi"[..]), + ErrorKind::Alt, + error_position!(Partial::new(&b"xyzabcdefghi"[..]), ErrorKind::Tag) + ))) + ); + + let e = &b"efgabc"[..]; + assert_eq!( + perm(Partial::new(e)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn separated0_test() { + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated0("abcd", ",").parse_next(i) + } + fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated0("", ",").parse_next(i) + } + fn multi_longsep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated0("abcd", "..").parse_next(i) + } + + let a = &b"abcdef"[..]; + let b = &b"abcd,abcdef"[..]; + let c = &b"azerty"[..]; + let d = &b",,abc"[..]; + let e = &b"abcd,abcd,ef"[..]; + let f = &b"abc"[..]; + let g = &b"abcd."[..]; + let h = &b"abcd,abc"[..]; + + let res1 = vec![&b"abcd"[..]]; + assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); + let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!(multi(Partial::new(b)), Ok((Partial::new(&b"ef"[..]), res2))); + assert_eq!( + multi(Partial::new(c)), + Ok((Partial::new(&b"azerty"[..]), Vec::new())) + ); + let res3 = vec![&b""[..], &b""[..], &b""[..]]; + assert_eq!( + multi_empty(Partial::new(d)), + Ok((Partial::new(&b"abc"[..]), res3)) + ); + let res4 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!( + multi(Partial::new(e)), + Ok((Partial::new(&b",ef"[..]), res4)) + ); + + assert_eq!( + multi(Partial::new(f)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + multi_longsep(Partial::new(g)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + multi(Partial::new(h)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +#[cfg_attr(debug_assertions, should_panic)] +fn separated0_empty_sep_test() { + fn empty_sep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated0("abc", "").parse_next(i) + } + + let i = &b"abcabc"[..]; + + let i_err_pos = &i[3..]; + assert_eq!( + empty_sep(Partial::new(i)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(i_err_pos), + ErrorKind::Assert + ))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn separated1_test() { + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated1("abcd", ",").parse_next(i) + } + fn multi_longsep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + separated1("abcd", "..").parse_next(i) + } + + let a = &b"abcdef"[..]; + let b = &b"abcd,abcdef"[..]; + let c = &b"azerty"[..]; + let d = &b"abcd,abcd,ef"[..]; + + let f = &b"abc"[..]; + let g = &b"abcd."[..]; + let h = &b"abcd,abc"[..]; + + let res1 = vec![&b"abcd"[..]]; + assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); + let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!(multi(Partial::new(b)), Ok((Partial::new(&b"ef"[..]), res2))); + assert_eq!( + multi(Partial::new(c)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(c), + ErrorKind::Tag + ))) + ); + let res3 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!( + multi(Partial::new(d)), + Ok((Partial::new(&b",ef"[..]), res3)) + ); + + assert_eq!( + multi(Partial::new(f)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + multi_longsep(Partial::new(g)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + multi(Partial::new(h)), + Err(ErrMode::Incomplete(Needed::new(1))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn repeat0_test() { + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + repeat(0.., "abcd").parse_next(i) + } + + assert_eq!( + multi(Partial::new(&b"abcdef"[..])), + Ok((Partial::new(&b"ef"[..]), vec![&b"abcd"[..]])) + ); + assert_eq!( + multi(Partial::new(&b"abcdabcdefgh"[..])), + Ok((Partial::new(&b"efgh"[..]), vec![&b"abcd"[..], &b"abcd"[..]])) + ); + assert_eq!( + multi(Partial::new(&b"azerty"[..])), + Ok((Partial::new(&b"azerty"[..]), Vec::new())) + ); + assert_eq!( + multi(Partial::new(&b"abcdab"[..])), + Err(ErrMode::Incomplete(Needed::new(2))) + ); + assert_eq!( + multi(Partial::new(&b"abcd"[..])), + Err(ErrMode::Incomplete(Needed::new(4))) + ); + assert_eq!( + multi(Partial::new(&b""[..])), + Err(ErrMode::Incomplete(Needed::new(4))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +#[cfg_attr(debug_assertions, should_panic)] +fn repeat0_empty_test() { + fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + repeat(0.., "").parse_next(i) + } + + assert_eq!( + multi_empty(Partial::new(&b"abcdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"abcdef"[..]), + ErrorKind::Assert + ))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn repeat1_test() { + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + repeat(1.., "abcd").parse_next(i) + } + + let a = &b"abcdef"[..]; + let b = &b"abcdabcdefgh"[..]; + let c = &b"azerty"[..]; + let d = &b"abcdab"[..]; + + let res1 = vec![&b"abcd"[..]]; + assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); + let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!( + multi(Partial::new(b)), + Ok((Partial::new(&b"efgh"[..]), res2)) + ); + assert_eq!( + multi(Partial::new(c)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(c), + ErrorKind::Tag + ))) + ); + assert_eq!( + multi(Partial::new(d)), + Err(ErrMode::Incomplete(Needed::new(2))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn repeat_till_test() { + #[allow(clippy::type_complexity)] + fn multi(i: &[u8]) -> IResult<&[u8], (Vec<&[u8]>, &[u8])> { + repeat_till0("abcd", "efgh").parse_next(i) + } + + let a = b"abcdabcdefghabcd"; + let b = b"efghabcd"; + let c = b"azerty"; + + let res_a = (vec![&b"abcd"[..], &b"abcd"[..]], &b"efgh"[..]); + let res_b: (Vec<&[u8]>, &[u8]) = (Vec::new(), &b"efgh"[..]); + assert_eq!(multi(&a[..]), Ok((&b"abcd"[..], res_a))); + assert_eq!(multi(&b[..]), Ok((&b"abcd"[..], res_b))); + assert_eq!( + multi(&c[..]), + Err(ErrMode::Backtrack(error_node_position!( + &c[..], + ErrorKind::Many, + error_position!(&c[..], ErrorKind::Tag) + ))) + ); +} + +#[test] +#[cfg(feature = "std")] +fn infinite_many() { + fn tst(input: &[u8]) -> IResult<&[u8], &[u8]> { + println!("input: {:?}", input); + Err(ErrMode::Backtrack(error_position!(input, ErrorKind::Tag))) + } + + // should not go into an infinite loop + fn multi0(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { + repeat(0.., tst).parse_next(i) + } + let a = &b"abcdef"[..]; + assert_eq!(multi0(a), Ok((a, Vec::new()))); + + fn multi1(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { + repeat(1.., tst).parse_next(i) + } + let a = &b"abcdef"[..]; + assert_eq!( + multi1(a), + Err(ErrMode::Backtrack(error_position!(a, ErrorKind::Tag))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn repeat_test() { + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + repeat(2..=4, "Abcd").parse_next(i) + } + + let a = &b"Abcdef"[..]; + let b = &b"AbcdAbcdefgh"[..]; + let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; + let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; + let e = &b"AbcdAb"[..]; + + assert_eq!( + multi(Partial::new(a)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"ef"[..]), + ErrorKind::Tag + ))) + ); + let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(b)), + Ok((Partial::new(&b"efgh"[..]), res1)) + ); + let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(c)), + Ok((Partial::new(&b"efgh"[..]), res2)) + ); + let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(d)), + Ok((Partial::new(&b"Abcdefgh"[..]), res3)) + ); + assert_eq!( + multi(Partial::new(e)), + Err(ErrMode::Incomplete(Needed::new(2))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn count_test() { + const TIMES: usize = 2; + fn cnt_2(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + repeat(TIMES, "abc").parse_next(i) + } + + assert_eq!( + cnt_2(Partial::new(&b"abcabcabcdef"[..])), + Ok((Partial::new(&b"abcdef"[..]), vec![&b"abc"[..], &b"abc"[..]])) + ); + assert_eq!( + cnt_2(Partial::new(&b"ab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + cnt_2(Partial::new(&b"abcab"[..])), + Err(ErrMode::Incomplete(Needed::new(1))) + ); + assert_eq!( + cnt_2(Partial::new(&b"xxx"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxx"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + cnt_2(Partial::new(&b"xxxabcabcdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxabcabcdef"[..]), + ErrorKind::Tag + ))) + ); + assert_eq!( + cnt_2(Partial::new(&b"abcxxxabcdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"xxxabcdef"[..]), + ErrorKind::Tag + ))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn count_zero() { + const TIMES: usize = 0; + fn counter_2(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { + repeat(TIMES, "abc").parse_next(i) + } + + let done = &b"abcabcabcdef"[..]; + let parsed_done = Vec::new(); + let rest = done; + let incomplete_1 = &b"ab"[..]; + let parsed_incompl_1 = Vec::new(); + let incomplete_2 = &b"abcab"[..]; + let parsed_incompl_2 = Vec::new(); + let error = &b"xxx"[..]; + let error_remain = &b"xxx"[..]; + let parsed_err = Vec::new(); + let error_1 = &b"xxxabcabcdef"[..]; + let parsed_err_1 = Vec::new(); + let error_1_remain = &b"xxxabcabcdef"[..]; + let error_2 = &b"abcxxxabcdef"[..]; + let parsed_err_2 = Vec::new(); + let error_2_remain = &b"abcxxxabcdef"[..]; + + assert_eq!(counter_2(done), Ok((rest, parsed_done))); + assert_eq!( + counter_2(incomplete_1), + Ok((incomplete_1, parsed_incompl_1)) + ); + assert_eq!( + counter_2(incomplete_2), + Ok((incomplete_2, parsed_incompl_2)) + ); + assert_eq!(counter_2(error), Ok((error_remain, parsed_err))); + assert_eq!(counter_2(error_1), Ok((error_1_remain, parsed_err_1))); + assert_eq!(counter_2(error_2), Ok((error_2_remain, parsed_err_2))); +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct NilError; + +impl<I> From<(I, ErrorKind)> for NilError { + fn from(_: (I, ErrorKind)) -> Self { + NilError + } +} + +impl<I> ParseError<I> for NilError { + fn from_error_kind(_: I, _: ErrorKind) -> NilError { + NilError + } + fn append(self, _: I, _: ErrorKind) -> NilError { + NilError + } +} + +#[test] +#[cfg(feature = "alloc")] +fn fold_repeat0_test() { + fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { + acc.push(item); + acc + } + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + fold_repeat(0.., "abcd", Vec::new, fold_into_vec).parse_next(i) + } + + assert_eq!( + multi(Partial::new(&b"abcdef"[..])), + Ok((Partial::new(&b"ef"[..]), vec![&b"abcd"[..]])) + ); + assert_eq!( + multi(Partial::new(&b"abcdabcdefgh"[..])), + Ok((Partial::new(&b"efgh"[..]), vec![&b"abcd"[..], &b"abcd"[..]])) + ); + assert_eq!( + multi(Partial::new(&b"azerty"[..])), + Ok((Partial::new(&b"azerty"[..]), Vec::new())) + ); + assert_eq!( + multi(Partial::new(&b"abcdab"[..])), + Err(ErrMode::Incomplete(Needed::new(2))) + ); + assert_eq!( + multi(Partial::new(&b"abcd"[..])), + Err(ErrMode::Incomplete(Needed::new(4))) + ); + assert_eq!( + multi(Partial::new(&b""[..])), + Err(ErrMode::Incomplete(Needed::new(4))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +#[cfg_attr(debug_assertions, should_panic)] +fn fold_repeat0_empty_test() { + fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { + acc.push(item); + acc + } + fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + fold_repeat(0.., "", Vec::new, fold_into_vec).parse_next(i) + } + + assert_eq!( + multi_empty(Partial::new(&b"abcdef"[..])), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"abcdef"[..]), + ErrorKind::Assert + ))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn fold_repeat1_test() { + fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { + acc.push(item); + acc + } + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + fold_repeat(1.., "abcd", Vec::new, fold_into_vec).parse_next(i) + } + + let a = &b"abcdef"[..]; + let b = &b"abcdabcdefgh"[..]; + let c = &b"azerty"[..]; + let d = &b"abcdab"[..]; + + let res1 = vec![&b"abcd"[..]]; + assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); + let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; + assert_eq!( + multi(Partial::new(b)), + Ok((Partial::new(&b"efgh"[..]), res2)) + ); + assert_eq!( + multi(Partial::new(c)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(c), + ErrorKind::Many + ))) + ); + assert_eq!( + multi(Partial::new(d)), + Err(ErrMode::Incomplete(Needed::new(2))) + ); +} + +#[test] +#[cfg(feature = "alloc")] +fn fold_repeat_test() { + fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { + acc.push(item); + acc + } + fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { + fold_repeat(2..=4, "Abcd", Vec::new, fold_into_vec).parse_next(i) + } + + let a = &b"Abcdef"[..]; + let b = &b"AbcdAbcdefgh"[..]; + let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; + let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; + let e = &b"AbcdAb"[..]; + + assert_eq!( + multi(Partial::new(a)), + Err(ErrMode::Backtrack(error_position!( + Partial::new(&b"ef"[..]), + ErrorKind::Tag + ))) + ); + let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(b)), + Ok((Partial::new(&b"efgh"[..]), res1)) + ); + let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(c)), + Ok((Partial::new(&b"efgh"[..]), res2)) + ); + let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; + assert_eq!( + multi(Partial::new(d)), + Ok((Partial::new(&b"Abcdefgh"[..]), res3)) + ); + assert_eq!( + multi(Partial::new(e)), + Err(ErrMode::Incomplete(Needed::new(2))) + ); +} + +#[test] +fn repeat0_count_test() { + fn count0_nums(i: &[u8]) -> IResult<&[u8], usize> { + repeat(0.., (digit, ",")).parse_next(i) + } + + assert_eq!(count0_nums(&b"123,junk"[..]), Ok((&b"junk"[..], 1))); + + assert_eq!(count0_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2))); + + assert_eq!( + count0_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), + Ok((&b"junk"[..], 10)) + ); + + assert_eq!(count0_nums(&b"hello"[..]), Ok((&b"hello"[..], 0))); +} + +#[test] +fn repeat1_count_test() { + fn count1_nums(i: &[u8]) -> IResult<&[u8], usize> { + repeat(1.., (digit, ",")).parse_next(i) + } + + assert_eq!(count1_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2))); + + assert_eq!( + count1_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), + Ok((&b"junk"[..], 10)) + ); + + assert_eq!( + count1_nums(&b"hello"[..]), + Err(ErrMode::Backtrack(error_position!( + &b"hello"[..], + ErrorKind::Slice + ))) + ); +} diff --git a/vendor/winnow/src/error.rs b/vendor/winnow/src/error.rs index b49b0560a..c92228621 100644 --- a/vendor/winnow/src/error.rs +++ b/vendor/winnow/src/error.rs @@ -58,10 +58,10 @@ pub trait FinishIResult<I, O, E> { /// /// # Example /// - #[cfg_attr(not(feature = "std"), doc = "```ignore")] - #[cfg_attr(feature = "std", doc = "```")] + /// ```rust + /// # #[cfg(feature = "std")] { /// use winnow::prelude::*; - /// use winnow::character::hex_uint; + /// use winnow::ascii::hex_uint; /// use winnow::error::Error; /// /// struct Hex(u64); @@ -69,6 +69,7 @@ pub trait FinishIResult<I, O, E> { /// fn parse(value: &str) -> Result<Hex, Error<String>> { /// hex_uint.map(Hex).parse_next(value).finish().map_err(Error::into_owned) /// } + /// # } /// ``` #[deprecated(since = "0.4.0", note = "Replaced with `Parser::parse`")] fn finish(self) -> Result<O, E>; @@ -176,7 +177,7 @@ pub enum ErrMode<E> { /// The parser failed with a recoverable error (the default). /// /// For example, a parser for json values might include a - /// [`dec_uint`][crate::character::dec_uint] as one case in an [`alt`][crate::branch::alt] + /// [`dec_uint`][crate::ascii::dec_uint] as one case in an [`alt`][crate::combinator::alt] /// combiantor. If it fails, the next case should be tried. Backtrack(E), /// The parser had an unrecoverable error. @@ -185,7 +186,7 @@ pub enum ErrMode<E> { /// other branches. You can use [`cut_err()`][crate::combinator::cut_err] combinator to switch /// from `ErrMode::Backtrack` to `ErrMode::Cut`. /// - /// For example, one case in an [`alt`][crate::branch::alt] combinator found a unique prefix + /// For example, one case in an [`alt`][crate::combinator::alt] combinator found a unique prefix /// and you want any further errors parsing the case to be reported to the user. Cut(E), } @@ -335,7 +336,7 @@ pub trait ParseError<I>: Sized { /// Combines errors from two different parse branches. /// - /// For example, this would be used by [`alt`][crate::branch::alt] to report the error from + /// For example, this would be used by [`alt`][crate::combinator::alt] to report the error from /// each case. fn or(self, other: Self) -> Self { other @@ -357,7 +358,7 @@ pub trait ContextError<I, C = &'static str>: Sized { /// Create a new error with an external error, from [`std::str::FromStr`] /// -/// This trait is required by the [`Parser::map_res`] combinator. +/// This trait is required by the [`Parser::try_map`] combinator. pub trait FromExternalError<I, E> { /// Like [`ParseError::from_error_kind`] but also include an external error. fn from_external_error(input: I, kind: ErrorKind, e: E) -> Self; @@ -374,7 +375,7 @@ pub trait ErrorConvert<E> { /// This is a low-overhead error that only provides basic information. For less overhead, see /// `()`. Fore more information, see [`VerboseError`]. ///:w -/// **Note:** [context][Parser::context] and inner errors (like from [`Parser::map_res`]) will be +/// **Note:** [context][Parser::context] and inner errors (like from [`Parser::try_map`]) will be /// dropped. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Error<I> { @@ -472,7 +473,7 @@ impl ErrorConvert<()> for () { /// [`convert_error`] provides an example of how to render this for end-users. /// /// **Note:** This will only capture the last failed branch for combinators like -/// [`alt`][crate::branch::alt]. +/// [`alt`][crate::combinator::alt]. #[cfg(feature = "alloc")] #[derive(Clone, Debug, Eq, PartialEq)] pub struct VerboseError<I> { diff --git a/vendor/winnow/src/lib.rs b/vendor/winnow/src/lib.rs index ddbc8f812..3b6066230 100644 --- a/vendor/winnow/src/lib.rs +++ b/vendor/winnow/src/lib.rs @@ -24,7 +24,7 @@ //! - Resilient maintainership, including //! - Willing to break compatibility rather than batching up breaking changes in large releases //! - Leverage feature flags to keep one active branch -//! - We will support the last 6 months of rust releases (MSRV, currently 1.60) +//! - We will support the last 6 months of rust releases (MSRV, currently 1.64.0) //! //! See also [Special Topic: Why winnow?][crate::_topic::why] //! @@ -48,7 +48,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(extended_key_value_attributes))] #![cfg_attr(not(feature = "std"), no_std)] -#![deny(missing_docs)] +#![warn(missing_docs)] // BEGIN - Embark standard lints v6 for Rust 1.55+ // do not change or add/remove here, but one can add exceptions after this section // for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59> @@ -199,6 +199,8 @@ mod parser; pub mod stream; +pub mod ascii; +pub mod binary; pub mod bits; pub mod branch; pub mod bytes; @@ -207,6 +209,7 @@ pub mod combinator; pub mod multi; pub mod number; pub mod sequence; +pub mod token; pub mod trace; #[cfg(feature = "unstable-doc")] @@ -227,7 +230,7 @@ pub mod _tutorial; /// /// fn parse_data(input: &str) -> IResult<&str, u64> { /// // ... -/// # winnow::character::dec_uint(input) +/// # winnow::ascii::dec_uint(input) /// } /// /// fn main() { diff --git a/vendor/winnow/src/macros.rs b/vendor/winnow/src/macros.rs index bec67c1a3..8a38ef25c 100644 --- a/vendor/winnow/src/macros.rs +++ b/vendor/winnow/src/macros.rs @@ -1,7 +1,7 @@ /// `match` for parsers /// /// When parsers have unique prefixes to test for, this offers better performance over -/// [`alt`][crate::branch::alt] though it might be at the cost of duplicating parts of your grammar +/// [`alt`][crate::combinator::alt] though it might be at the cost of duplicating parts of your grammar /// if you needed to [`peek`][crate::combinator::peek]. /// /// For tight control over the error in a catch-all case, use [`fail`][crate::combinator::fail]. @@ -10,10 +10,10 @@ /// /// ```rust /// use winnow::prelude::*; -/// use winnow::branch::dispatch; -/// # use winnow::bytes::any; +/// use winnow::combinator::dispatch; +/// # use winnow::token::any; /// # use winnow::combinator::peek; -/// # use winnow::sequence::preceded; +/// # use winnow::combinator::preceded; /// # use winnow::combinator::success; /// # use winnow::combinator::fail; /// diff --git a/vendor/winnow/src/multi.rs b/vendor/winnow/src/multi.rs new file mode 100644 index 000000000..3e92f70be --- /dev/null +++ b/vendor/winnow/src/multi.rs @@ -0,0 +1,124 @@ +//! Deprecated, see [`combinator`] +#![deprecated(since = "0.4.2", note = "Replaced with `combinator`")] + +use crate::binary; +use crate::combinator; +use crate::error::ParseError; +use crate::stream::Accumulate; +use crate::stream::Stream; +use crate::Parser; + +/// Deprecated, replaced by [`combinator::repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::repeat`")] +#[inline(always)] +pub fn many0<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + combinator::repeat(0.., f) +} + +/// Deprecated, replaced by [`combinator::repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::repeat`")] +#[inline(always)] +pub fn many1<I, O, C, E, F>(f: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + combinator::repeat(1.., f) +} + +/// Deprecated, replaced by [`combinator::repeat_till0`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::repeat_till0`")] +#[inline(always)] +pub fn many_till0<I, O, C, P, E, F, G>(f: F, g: G) -> impl Parser<I, (C, P), E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + G: Parser<I, P, E>, + E: ParseError<I>, +{ + combinator::repeat_till0(f, g) +} + +pub use combinator::separated0; +pub use combinator::separated1; +pub use combinator::separated_foldl1; +#[cfg(feature = "alloc")] +pub use combinator::separated_foldr1; + +/// Deprecated, replaced by [`combinator::repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::repeat`")] +#[inline(always)] +pub fn many_m_n<I, O, C, E, F>(min: usize, max: usize, parse: F) -> impl Parser<I, C, E> +where + I: Stream, + C: Accumulate<O>, + F: Parser<I, O, E>, + E: ParseError<I>, +{ + combinator::repeat(min..=max, parse) +} + +#[allow(deprecated)] +pub use combinator::count; +pub use combinator::fill; + +/// Deprecated, replaced by [`combinator::fold_repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::fold_repeat`")] +#[inline(always)] +pub fn fold_many0<I, O, E, F, G, H, R>(f: F, init: H, g: G) -> impl Parser<I, R, E> +where + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, + E: ParseError<I>, +{ + combinator::fold_repeat(0.., f, init, g) +} + +/// Deprecated, replaced by [`combinator::fold_repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::fold_repeat`")] +#[inline(always)] +pub fn fold_many1<I, O, E, F, G, H, R>(f: F, init: H, g: G) -> impl Parser<I, R, E> +where + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, + E: ParseError<I>, +{ + combinator::fold_repeat(1.., f, init, g) +} + +/// Deprecated, replaced by [`combinator::fold_repeat`] +#[deprecated(since = "0.4.2", note = "Replaced with `combinator::fold_repeat`")] +#[inline(always)] +pub fn fold_many_m_n<I, O, E, F, G, H, R>( + min: usize, + max: usize, + parse: F, + init: H, + fold: G, +) -> impl Parser<I, R, E> +where + I: Stream, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, + H: FnMut() -> R, + E: ParseError<I>, +{ + combinator::fold_repeat(min..=max, parse, init, fold) +} + +pub use binary::length_count; +pub use binary::length_data; +pub use binary::length_value; diff --git a/vendor/winnow/src/multi/tests.rs b/vendor/winnow/src/multi/tests.rs deleted file mode 100644 index 1977ff9c1..000000000 --- a/vendor/winnow/src/multi/tests.rs +++ /dev/null @@ -1,743 +0,0 @@ -use super::{length_data, length_value, many0, many1}; -use crate::Parser; -use crate::Partial; -use crate::{ - character::digit1 as digit, - error::{ErrMode, ErrorKind, Needed, ParseError}, - lib::std::str::{self, FromStr}, - number::{be_u16, be_u8}, - IResult, -}; -#[cfg(feature = "alloc")] -use crate::{ - lib::std::vec::Vec, - multi::{ - count, fold_many0, fold_many1, fold_many_m_n, length_count, many_m_n, many_till0, - separated0, separated1, - }, -}; - -#[test] -#[cfg(feature = "alloc")] -fn separated0_test() { - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated0("abcd", ",").parse_next(i) - } - fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated0("", ",").parse_next(i) - } - fn multi_longsep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated0("abcd", "..").parse_next(i) - } - - let a = &b"abcdef"[..]; - let b = &b"abcd,abcdef"[..]; - let c = &b"azerty"[..]; - let d = &b",,abc"[..]; - let e = &b"abcd,abcd,ef"[..]; - let f = &b"abc"[..]; - let g = &b"abcd."[..]; - let h = &b"abcd,abc"[..]; - - let res1 = vec![&b"abcd"[..]]; - assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); - let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!(multi(Partial::new(b)), Ok((Partial::new(&b"ef"[..]), res2))); - assert_eq!( - multi(Partial::new(c)), - Ok((Partial::new(&b"azerty"[..]), Vec::new())) - ); - let res3 = vec![&b""[..], &b""[..], &b""[..]]; - assert_eq!( - multi_empty(Partial::new(d)), - Ok((Partial::new(&b"abc"[..]), res3)) - ); - let res4 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!( - multi(Partial::new(e)), - Ok((Partial::new(&b",ef"[..]), res4)) - ); - - assert_eq!( - multi(Partial::new(f)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - multi_longsep(Partial::new(g)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - multi(Partial::new(h)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -#[cfg_attr(debug_assertions, should_panic)] -fn separated0_empty_sep_test() { - fn empty_sep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated0("abc", "").parse_next(i) - } - - let i = &b"abcabc"[..]; - - let i_err_pos = &i[3..]; - assert_eq!( - empty_sep(Partial::new(i)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(i_err_pos), - ErrorKind::Assert - ))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn separated1_test() { - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated1("abcd", ",").parse_next(i) - } - fn multi_longsep(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - separated1("abcd", "..").parse_next(i) - } - - let a = &b"abcdef"[..]; - let b = &b"abcd,abcdef"[..]; - let c = &b"azerty"[..]; - let d = &b"abcd,abcd,ef"[..]; - - let f = &b"abc"[..]; - let g = &b"abcd."[..]; - let h = &b"abcd,abc"[..]; - - let res1 = vec![&b"abcd"[..]]; - assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); - let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!(multi(Partial::new(b)), Ok((Partial::new(&b"ef"[..]), res2))); - assert_eq!( - multi(Partial::new(c)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(c), - ErrorKind::Tag - ))) - ); - let res3 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!( - multi(Partial::new(d)), - Ok((Partial::new(&b",ef"[..]), res3)) - ); - - assert_eq!( - multi(Partial::new(f)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - multi_longsep(Partial::new(g)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - multi(Partial::new(h)), - Err(ErrMode::Incomplete(Needed::new(1))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn many0_test() { - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - many0("abcd").parse_next(i) - } - - assert_eq!( - multi(Partial::new(&b"abcdef"[..])), - Ok((Partial::new(&b"ef"[..]), vec![&b"abcd"[..]])) - ); - assert_eq!( - multi(Partial::new(&b"abcdabcdefgh"[..])), - Ok((Partial::new(&b"efgh"[..]), vec![&b"abcd"[..], &b"abcd"[..]])) - ); - assert_eq!( - multi(Partial::new(&b"azerty"[..])), - Ok((Partial::new(&b"azerty"[..]), Vec::new())) - ); - assert_eq!( - multi(Partial::new(&b"abcdab"[..])), - Err(ErrMode::Incomplete(Needed::new(2))) - ); - assert_eq!( - multi(Partial::new(&b"abcd"[..])), - Err(ErrMode::Incomplete(Needed::new(4))) - ); - assert_eq!( - multi(Partial::new(&b""[..])), - Err(ErrMode::Incomplete(Needed::new(4))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -#[cfg_attr(debug_assertions, should_panic)] -fn many0_empty_test() { - fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - many0("").parse_next(i) - } - - assert_eq!( - multi_empty(Partial::new(&b"abcdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"abcdef"[..]), - ErrorKind::Assert - ))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn many1_test() { - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - many1("abcd").parse_next(i) - } - - let a = &b"abcdef"[..]; - let b = &b"abcdabcdefgh"[..]; - let c = &b"azerty"[..]; - let d = &b"abcdab"[..]; - - let res1 = vec![&b"abcd"[..]]; - assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); - let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!( - multi(Partial::new(b)), - Ok((Partial::new(&b"efgh"[..]), res2)) - ); - assert_eq!( - multi(Partial::new(c)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(c), - ErrorKind::Tag - ))) - ); - assert_eq!( - multi(Partial::new(d)), - Err(ErrMode::Incomplete(Needed::new(2))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn many_till_test() { - #[allow(clippy::type_complexity)] - fn multi(i: &[u8]) -> IResult<&[u8], (Vec<&[u8]>, &[u8])> { - many_till0("abcd", "efgh").parse_next(i) - } - - let a = b"abcdabcdefghabcd"; - let b = b"efghabcd"; - let c = b"azerty"; - - let res_a = (vec![&b"abcd"[..], &b"abcd"[..]], &b"efgh"[..]); - let res_b: (Vec<&[u8]>, &[u8]) = (Vec::new(), &b"efgh"[..]); - assert_eq!(multi(&a[..]), Ok((&b"abcd"[..], res_a))); - assert_eq!(multi(&b[..]), Ok((&b"abcd"[..], res_b))); - assert_eq!( - multi(&c[..]), - Err(ErrMode::Backtrack(error_node_position!( - &c[..], - ErrorKind::Many, - error_position!(&c[..], ErrorKind::Tag) - ))) - ); -} - -#[test] -#[cfg(feature = "std")] -fn infinite_many() { - fn tst(input: &[u8]) -> IResult<&[u8], &[u8]> { - println!("input: {:?}", input); - Err(ErrMode::Backtrack(error_position!(input, ErrorKind::Tag))) - } - - // should not go into an infinite loop - fn multi0(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { - many0(tst).parse_next(i) - } - let a = &b"abcdef"[..]; - assert_eq!(multi0(a), Ok((a, Vec::new()))); - - fn multi1(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { - many1(tst).parse_next(i) - } - let a = &b"abcdef"[..]; - assert_eq!( - multi1(a), - Err(ErrMode::Backtrack(error_position!(a, ErrorKind::Tag))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn many_m_n_test() { - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - many_m_n(2, 4, "Abcd").parse_next(i) - } - - let a = &b"Abcdef"[..]; - let b = &b"AbcdAbcdefgh"[..]; - let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; - let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; - let e = &b"AbcdAb"[..]; - - assert_eq!( - multi(Partial::new(a)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"ef"[..]), - ErrorKind::Tag - ))) - ); - let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(b)), - Ok((Partial::new(&b"efgh"[..]), res1)) - ); - let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(c)), - Ok((Partial::new(&b"efgh"[..]), res2)) - ); - let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(d)), - Ok((Partial::new(&b"Abcdefgh"[..]), res3)) - ); - assert_eq!( - multi(Partial::new(e)), - Err(ErrMode::Incomplete(Needed::new(2))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn count_test() { - const TIMES: usize = 2; - fn cnt_2(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - count("abc", TIMES).parse_next(i) - } - - assert_eq!( - cnt_2(Partial::new(&b"abcabcabcdef"[..])), - Ok((Partial::new(&b"abcdef"[..]), vec![&b"abc"[..], &b"abc"[..]])) - ); - assert_eq!( - cnt_2(Partial::new(&b"ab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - cnt_2(Partial::new(&b"abcab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - cnt_2(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - cnt_2(Partial::new(&b"xxxabcabcdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxabcabcdef"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - cnt_2(Partial::new(&b"abcxxxabcdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxabcdef"[..]), - ErrorKind::Tag - ))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn count_zero() { - const TIMES: usize = 0; - fn counter_2(i: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { - count("abc", TIMES).parse_next(i) - } - - let done = &b"abcabcabcdef"[..]; - let parsed_done = Vec::new(); - let rest = done; - let incomplete_1 = &b"ab"[..]; - let parsed_incompl_1 = Vec::new(); - let incomplete_2 = &b"abcab"[..]; - let parsed_incompl_2 = Vec::new(); - let error = &b"xxx"[..]; - let error_remain = &b"xxx"[..]; - let parsed_err = Vec::new(); - let error_1 = &b"xxxabcabcdef"[..]; - let parsed_err_1 = Vec::new(); - let error_1_remain = &b"xxxabcabcdef"[..]; - let error_2 = &b"abcxxxabcdef"[..]; - let parsed_err_2 = Vec::new(); - let error_2_remain = &b"abcxxxabcdef"[..]; - - assert_eq!(counter_2(done), Ok((rest, parsed_done))); - assert_eq!( - counter_2(incomplete_1), - Ok((incomplete_1, parsed_incompl_1)) - ); - assert_eq!( - counter_2(incomplete_2), - Ok((incomplete_2, parsed_incompl_2)) - ); - assert_eq!(counter_2(error), Ok((error_remain, parsed_err))); - assert_eq!(counter_2(error_1), Ok((error_1_remain, parsed_err_1))); - assert_eq!(counter_2(error_2), Ok((error_2_remain, parsed_err_2))); -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct NilError; - -impl<I> From<(I, ErrorKind)> for NilError { - fn from(_: (I, ErrorKind)) -> Self { - NilError - } -} - -impl<I> ParseError<I> for NilError { - fn from_error_kind(_: I, _: ErrorKind) -> NilError { - NilError - } - fn append(self, _: I, _: ErrorKind) -> NilError { - NilError - } -} - -#[test] -#[cfg(feature = "alloc")] -fn length_count_test() { - fn number(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { - digit - .map_res(str::from_utf8) - .map_res(FromStr::from_str) - .parse_next(i) - } - - fn cnt(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - length_count(number, "abc").parse_next(i) - } - - assert_eq!( - cnt(Partial::new(&b"2abcabcabcdef"[..])), - Ok((Partial::new(&b"abcdef"[..]), vec![&b"abc"[..], &b"abc"[..]])) - ); - assert_eq!( - cnt(Partial::new(&b"2ab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - cnt(Partial::new(&b"3abcab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - cnt(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Slice - ))) - ); - assert_eq!( - cnt(Partial::new(&b"2abcxxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); -} - -#[test] -fn length_data_test() { - fn number(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> { - digit - .map_res(str::from_utf8) - .map_res(FromStr::from_str) - .parse_next(i) - } - - fn take(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - length_data(number).parse_next(i) - } - - assert_eq!( - take(Partial::new(&b"6abcabcabcdef"[..])), - Ok((Partial::new(&b"abcdef"[..]), &b"abcabc"[..])) - ); - assert_eq!( - take(Partial::new(&b"3ab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - take(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Slice - ))) - ); - assert_eq!( - take(Partial::new(&b"2abcxxx"[..])), - Ok((Partial::new(&b"cxxx"[..]), &b"ab"[..])) - ); -} - -#[test] -fn length_value_test() { - use crate::stream::StreamIsPartial; - - fn length_value_1(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> { - length_value(be_u8, be_u16).parse_next(i) - } - fn length_value_2(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u8, u8)> { - length_value(be_u8, (be_u8, be_u8)).parse_next(i) - } - - let mut empty_complete = Partial::new(&b""[..]); - let _ = empty_complete.complete(); - - let i1 = [0, 5, 6]; - assert_eq!( - length_value_1(Partial::new(&i1)), - Err(ErrMode::Backtrack(error_position!( - empty_complete, - ErrorKind::Slice - ))) - ); - assert_eq!( - length_value_2(Partial::new(&i1)), - Err(ErrMode::Backtrack(error_position!( - empty_complete, - ErrorKind::Token - ))) - ); - - let i2 = [1, 5, 6, 3]; - { - let mut middle_complete = Partial::new(&i2[1..2]); - let _ = middle_complete.complete(); - assert_eq!( - length_value_1(Partial::new(&i2)), - Err(ErrMode::Backtrack(error_position!( - middle_complete, - ErrorKind::Slice - ))) - ); - assert_eq!( - length_value_2(Partial::new(&i2)), - Err(ErrMode::Backtrack(error_position!( - empty_complete, - ErrorKind::Token - ))) - ); - } - - let i3 = [2, 5, 6, 3, 4, 5, 7]; - assert_eq!( - length_value_1(Partial::new(&i3)), - Ok((Partial::new(&i3[3..]), 1286)) - ); - assert_eq!( - length_value_2(Partial::new(&i3)), - Ok((Partial::new(&i3[3..]), (5, 6))) - ); - - let i4 = [3, 5, 6, 3, 4, 5]; - assert_eq!( - length_value_1(Partial::new(&i4)), - Ok((Partial::new(&i4[4..]), 1286)) - ); - assert_eq!( - length_value_2(Partial::new(&i4)), - Ok((Partial::new(&i4[4..]), (5, 6))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn fold_many0_test() { - fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { - acc.push(item); - acc - } - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - fold_many0("abcd", Vec::new, fold_into_vec).parse_next(i) - } - - assert_eq!( - multi(Partial::new(&b"abcdef"[..])), - Ok((Partial::new(&b"ef"[..]), vec![&b"abcd"[..]])) - ); - assert_eq!( - multi(Partial::new(&b"abcdabcdefgh"[..])), - Ok((Partial::new(&b"efgh"[..]), vec![&b"abcd"[..], &b"abcd"[..]])) - ); - assert_eq!( - multi(Partial::new(&b"azerty"[..])), - Ok((Partial::new(&b"azerty"[..]), Vec::new())) - ); - assert_eq!( - multi(Partial::new(&b"abcdab"[..])), - Err(ErrMode::Incomplete(Needed::new(2))) - ); - assert_eq!( - multi(Partial::new(&b"abcd"[..])), - Err(ErrMode::Incomplete(Needed::new(4))) - ); - assert_eq!( - multi(Partial::new(&b""[..])), - Err(ErrMode::Incomplete(Needed::new(4))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -#[cfg_attr(debug_assertions, should_panic)] -fn fold_many0_empty_test() { - fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { - acc.push(item); - acc - } - fn multi_empty(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - fold_many0("", Vec::new, fold_into_vec).parse_next(i) - } - - assert_eq!( - multi_empty(Partial::new(&b"abcdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"abcdef"[..]), - ErrorKind::Assert - ))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn fold_many1_test() { - fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { - acc.push(item); - acc - } - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - fold_many1("abcd", Vec::new, fold_into_vec).parse_next(i) - } - - let a = &b"abcdef"[..]; - let b = &b"abcdabcdefgh"[..]; - let c = &b"azerty"[..]; - let d = &b"abcdab"[..]; - - let res1 = vec![&b"abcd"[..]]; - assert_eq!(multi(Partial::new(a)), Ok((Partial::new(&b"ef"[..]), res1))); - let res2 = vec![&b"abcd"[..], &b"abcd"[..]]; - assert_eq!( - multi(Partial::new(b)), - Ok((Partial::new(&b"efgh"[..]), res2)) - ); - assert_eq!( - multi(Partial::new(c)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(c), - ErrorKind::Many - ))) - ); - assert_eq!( - multi(Partial::new(d)), - Err(ErrMode::Incomplete(Needed::new(2))) - ); -} - -#[test] -#[cfg(feature = "alloc")] -fn fold_many_m_n_test() { - fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> { - acc.push(item); - acc - } - fn multi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, Vec<&[u8]>> { - fold_many_m_n(2, 4, "Abcd", Vec::new, fold_into_vec).parse_next(i) - } - - let a = &b"Abcdef"[..]; - let b = &b"AbcdAbcdefgh"[..]; - let c = &b"AbcdAbcdAbcdAbcdefgh"[..]; - let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..]; - let e = &b"AbcdAb"[..]; - - assert_eq!( - multi(Partial::new(a)), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"ef"[..]), - ErrorKind::Tag - ))) - ); - let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(b)), - Ok((Partial::new(&b"efgh"[..]), res1)) - ); - let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(c)), - Ok((Partial::new(&b"efgh"[..]), res2)) - ); - let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]]; - assert_eq!( - multi(Partial::new(d)), - Ok((Partial::new(&b"Abcdefgh"[..]), res3)) - ); - assert_eq!( - multi(Partial::new(e)), - Err(ErrMode::Incomplete(Needed::new(2))) - ); -} - -#[test] -fn many0_count_test() { - fn count0_nums(i: &[u8]) -> IResult<&[u8], usize> { - many0((digit, ",")).parse_next(i) - } - - assert_eq!(count0_nums(&b"123,junk"[..]), Ok((&b"junk"[..], 1))); - - assert_eq!(count0_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2))); - - assert_eq!( - count0_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), - Ok((&b"junk"[..], 10)) - ); - - assert_eq!(count0_nums(&b"hello"[..]), Ok((&b"hello"[..], 0))); -} - -#[test] -fn many1_count_test() { - fn count1_nums(i: &[u8]) -> IResult<&[u8], usize> { - many1((digit, ",")).parse_next(i) - } - - assert_eq!(count1_nums(&b"123,45,junk"[..]), Ok((&b"junk"[..], 2))); - - assert_eq!( - count1_nums(&b"1,2,3,4,5,6,7,8,9,0,junk"[..]), - Ok((&b"junk"[..], 10)) - ); - - assert_eq!( - count1_nums(&b"hello"[..]), - Err(ErrMode::Backtrack(error_position!( - &b"hello"[..], - ErrorKind::Slice - ))) - ); -} diff --git a/vendor/winnow/src/number.rs b/vendor/winnow/src/number.rs new file mode 100644 index 000000000..2aa8da425 --- /dev/null +++ b/vendor/winnow/src/number.rs @@ -0,0 +1,509 @@ +//! Deprecated, see [`binary`] +#![deprecated(since = "0.4.2", note = "Replaced with `binary`")] +#![allow(clippy::match_same_arms)] + +use crate::binary; +use crate::error::ParseError; +use crate::stream::{AsBytes, Stream, StreamIsPartial}; +use crate::IResult; +use crate::Parser; + +pub use binary::Endianness; + +/// Deprecated, see [`binary::be_u8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u8`")] +#[inline(always)] +pub fn be_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::be_u8(input) +} + +/// Deprecated, see [`binary::be_u16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u16`")] +#[inline(always)] +pub fn be_u16<I, E: ParseError<I>>(input: I) -> IResult<I, u16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_u16(input) +} + +/// Deprecated, see [`binary::be_u24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u24`")] +#[inline(always)] +pub fn be_u24<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_u24(input) +} + +/// Deprecated, see [`binary::be_u32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u32`")] +#[inline(always)] +pub fn be_u32<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_u32(input) +} + +/// Deprecated, see [`binary::be_u64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u64`")] +#[inline(always)] +pub fn be_u64<I, E: ParseError<I>>(input: I) -> IResult<I, u64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_u64(input) +} + +/// Deprecated, see [`binary::be_u128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_u128`")] +#[inline(always)] +pub fn be_u128<I, E: ParseError<I>>(input: I) -> IResult<I, u128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_u128(input) +} + +/// Deprecated, see [`binary::be_i8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i8`")] +#[inline(always)] +pub fn be_i8<I, E: ParseError<I>>(input: I) -> IResult<I, i8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::be_i8(input) +} + +/// Deprecated, see [`binary::be_i16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i16`")] +#[inline(always)] +pub fn be_i16<I, E: ParseError<I>>(input: I) -> IResult<I, i16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_i16(input) +} + +/// Deprecated, see [`binary::be_i24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i24`")] +#[inline(always)] +pub fn be_i24<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_i24(input) +} + +/// Deprecated, see [`binary::be_i32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i32`")] +#[inline(always)] +pub fn be_i32<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_i32(input) +} + +/// Deprecated, see [`binary::be_i64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i64`")] +#[inline(always)] +pub fn be_i64<I, E: ParseError<I>>(input: I) -> IResult<I, i64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_i64(input) +} + +/// Deprecated, see [`binary::be_i128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_i128`")] +#[inline(always)] +pub fn be_i128<I, E: ParseError<I>>(input: I) -> IResult<I, i128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_i128(input) +} + +/// Deprecated, see [`binary::le_u8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u8`")] +#[inline(always)] +pub fn le_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::le_u8(input) +} + +/// Deprecated, see [`binary::le_u16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u16`")] +#[inline(always)] +pub fn le_u16<I, E: ParseError<I>>(input: I) -> IResult<I, u16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_u16(input) +} + +/// Deprecated, see [`binary::le_u24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u24`")] +#[inline(always)] +pub fn le_u24<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_u24(input) +} + +/// Deprecated, see [`binary::le_u32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u32`")] +#[inline(always)] +pub fn le_u32<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_u32(input) +} + +/// Deprecated, see [`binary::le_u64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u64`")] +#[inline(always)] +pub fn le_u64<I, E: ParseError<I>>(input: I) -> IResult<I, u64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_u64(input) +} + +/// Deprecated, see [`binary::le_u128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_u128`")] +#[inline(always)] +pub fn le_u128<I, E: ParseError<I>>(input: I) -> IResult<I, u128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_u128(input) +} + +/// Deprecated, see [`binary::le_i8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i8`")] +#[inline(always)] +pub fn le_i8<I, E: ParseError<I>>(input: I) -> IResult<I, i8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::le_i8(input) +} + +/// Deprecated, see [`binary::le_i16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i16`")] +#[inline(always)] +pub fn le_i16<I, E: ParseError<I>>(input: I) -> IResult<I, i16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_i16(input) +} + +/// Deprecated, see [`binary::le_i24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i24`")] +#[inline(always)] +pub fn le_i24<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_i24(input) +} + +/// Deprecated, see [`binary::le_i32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i32`")] +#[inline(always)] +pub fn le_i32<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_i32(input) +} + +/// Deprecated, see [`binary::le_i64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i64`")] +#[inline(always)] +pub fn le_i64<I, E: ParseError<I>>(input: I) -> IResult<I, i64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_i64(input) +} + +/// Deprecated, see [`binary::le_i128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_i128`")] +#[inline(always)] +pub fn le_i128<I, E: ParseError<I>>(input: I) -> IResult<I, i128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_i128(input) +} + +/// Deprecated, see [`binary::u8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u8`")] +#[inline(always)] +pub fn u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::u8.parse_next(input) +} + +/// Deprecated, see [`binary::u16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u16`")] +#[inline(always)] +pub fn u16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::u16(endian) +} + +/// Deprecated, see [`binary::u24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u24`")] +#[inline(always)] +pub fn u24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::u24(endian) +} + +/// Deprecated, see [`binary::u32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u32`")] +#[inline(always)] +pub fn u32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::u32(endian) +} + +/// Deprecated, see [`binary::u64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u64`")] +#[inline(always)] +pub fn u64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::u64(endian) +} + +/// Deprecated, see [`binary::u128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::u128`")] +#[inline(always)] +pub fn u128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, u128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::u128(endian) +} + +/// Deprecated, see [`binary::i8`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i8`")] +#[inline(always)] +pub fn i8<I, E: ParseError<I>>(input: I) -> IResult<I, i8, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, +{ + binary::i8.parse_next(input) +} + +/// Deprecated, see [`binary::i16`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i16`")] +#[inline(always)] +pub fn i16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i16, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::i16(endian) +} + +/// Deprecated, see [`binary::i24`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i24`")] +#[inline(always)] +pub fn i24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::i24(endian) +} + +/// Deprecated, see [`binary::i32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i32`")] +#[inline(always)] +pub fn i32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::i32(endian) +} + +/// Deprecated, see [`binary::i64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i64`")] +#[inline(always)] +pub fn i64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::i64(endian) +} + +/// Deprecated, see [`binary::i128`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::i128`")] +#[inline(always)] +pub fn i128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, i128, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::i128(endian) +} + +/// Deprecated, see [`binary::be_f32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_f32`")] +#[inline(always)] +pub fn be_f32<I, E: ParseError<I>>(input: I) -> IResult<I, f32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_f32(input) +} + +/// Deprecated, see [`binary::be_f64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::be_f64`")] +#[inline(always)] +pub fn be_f64<I, E: ParseError<I>>(input: I) -> IResult<I, f64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::be_f64(input) +} + +/// Deprecated, see [`binary::le_f32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_f32`")] +#[inline(always)] +pub fn le_f32<I, E: ParseError<I>>(input: I) -> IResult<I, f32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_f32(input) +} + +/// Deprecated, see [`binary::le_f64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::le_f64`")] +#[inline(always)] +pub fn le_f64<I, E: ParseError<I>>(input: I) -> IResult<I, f64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::le_f64(input) +} + +/// Deprecated, see [`binary::f32`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::f32`")] +#[inline(always)] +pub fn f32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, f32, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::f32(endian) +} + +/// Deprecated, see [`binary::f64`] +#[deprecated(since = "0.4.2", note = "Replaced with `binary::f64`")] +#[inline(always)] +pub fn f64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> impl Parser<I, f64, E> +where + I: StreamIsPartial, + I: Stream<Token = u8>, + <I as Stream>::Slice: AsBytes, +{ + binary::f64(endian) +} diff --git a/vendor/winnow/src/parser.rs b/vendor/winnow/src/parser.rs index 264159094..15d892864 100644 --- a/vendor/winnow/src/parser.rs +++ b/vendor/winnow/src/parser.rs @@ -36,10 +36,11 @@ use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, Strea /// ``` /// /// Additionally, some basic types implement `Parser` as well, including -/// - `u8` and `char`, see [`winnow::bytes::one_of`][crate::bytes::one_of] -/// - `&[u8]` and `&str`, see [`winnow::bytes::tag`][crate::bytes::tag] +/// - `u8` and `char`, see [`winnow::token::one_of`][crate::token::one_of] +/// - `&[u8]` and `&str`, see [`winnow::token::tag`][crate::token::tag] pub trait Parser<I, O, E> { /// Parse all of `input`, generating `O` from it + #[inline] fn parse(&mut self, input: I) -> Result<O, E> where I: Stream, @@ -65,14 +66,14 @@ pub trait Parser<I, O, E> { /// # Example /// /// Because parsers are `FnMut`, they can be called multiple times. This prevents moving `f` - /// into [`length_data`][crate::multi::length_data] and `g` into + /// into [`length_data`][crate::binary::length_data] and `g` into /// [`Parser::complete_err`]: /// ```rust,compile_fail /// # use winnow::prelude::*; /// # use winnow::IResult; /// # use winnow::Parser; /// # use winnow::error::ParseError; - /// # use winnow::multi::length_data; + /// # use winnow::binary::length_data; /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( /// mut f: impl Parser<&'i [u8], usize, E>, /// mut g: impl Parser<&'i [u8], O, E> @@ -91,7 +92,7 @@ pub trait Parser<I, O, E> { /// # use winnow::IResult; /// # use winnow::Parser; /// # use winnow::error::ParseError; - /// # use winnow::multi::length_data; + /// # use winnow::binary::length_data; /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( /// mut f: impl Parser<&'i [u8], usize, E>, /// mut g: impl Parser<&'i [u8], O, E> @@ -116,7 +117,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::alpha1; + /// use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.value(1234); @@ -140,7 +141,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::alpha1; + /// use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.void(); @@ -163,7 +164,7 @@ pub trait Parser<I, O, E> { /// ```rust /// # use winnow::IResult; /// # use winnow::Parser; - /// use winnow::character::alpha1; + /// use winnow::ascii::alpha1; /// # fn main() { /// /// fn parser1(i: &str) -> IResult<&str, &str> { @@ -191,8 +192,8 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::{alpha1}; - /// use winnow::sequence::separated_pair; + /// use winnow::ascii::{alpha1}; + /// use winnow::combinator::separated_pair; /// # fn main() { /// /// let mut parser = separated_pair(alpha1, ',', alpha1).recognize(); @@ -225,9 +226,9 @@ pub trait Parser<I, O, E> { /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult}; - /// use winnow::character::{alpha1}; - /// use winnow::bytes::tag; - /// use winnow::sequence::separated_pair; + /// use winnow::ascii::{alpha1}; + /// use winnow::token::tag; + /// use winnow::combinator::separated_pair; /// /// fn inner_parser(input: &str) -> IResult<&str, bool> { /// "1234".value(true).parse_next(input) @@ -266,8 +267,8 @@ pub trait Parser<I, O, E> { /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, stream::Stream}; /// use winnow::stream::Located; - /// use winnow::character::alpha1; - /// use winnow::sequence::separated_pair; + /// use winnow::ascii::alpha1; + /// use winnow::combinator::separated_pair; /// /// let mut parser = separated_pair(alpha1.span(), ',', alpha1.span()); /// @@ -298,9 +299,9 @@ pub trait Parser<I, O, E> { /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, stream::Stream}; /// use winnow::stream::Located; - /// use winnow::character::alpha1; - /// use winnow::bytes::tag; - /// use winnow::sequence::separated_pair; + /// use winnow::ascii::alpha1; + /// use winnow::token::tag; + /// use winnow::combinator::separated_pair; /// /// fn inner_parser(input: Located<&str>) -> IResult<Located<&str>, bool> { /// "1234".value(true).parse_next(input) @@ -336,7 +337,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; - /// use winnow::character::digit1; + /// use winnow::ascii::digit1; /// # fn main() { /// /// let mut parser = digit1.map(|s: &str| s.len()); @@ -362,10 +363,10 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::digit1; + /// use winnow::ascii::digit1; /// # fn main() { /// - /// let mut parse = digit1.map_res(|s: &str| s.parse::<u8>()); + /// 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))); @@ -377,6 +378,18 @@ pub trait Parser<I, O, E> { /// assert_eq!(parse.parse_next("123456"), Err(ErrMode::Backtrack(Error::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, + 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, @@ -384,7 +397,7 @@ pub trait Parser<I, O, E> { I: Clone, E: FromExternalError<I, E2>, { - MapRes::new(self, map) + self.try_map(map) } /// Apply both [`Parser::verify`] and [`Parser::map`]. @@ -393,7 +406,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::digit1; + /// use winnow::ascii::digit1; /// # fn main() { /// /// let mut parse = digit1.verify_map(|s: &str| s.parse::<u8>().ok()); @@ -427,8 +440,8 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::bytes::take; - /// use winnow::number::u8; + /// use winnow::token::take; + /// use winnow::binary::u8; /// /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { /// u8.flat_map(take).parse_next(input) @@ -441,8 +454,8 @@ pub trait Parser<I, O, E> { /// which is the same as /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::bytes::take; - /// use winnow::number::u8; + /// use winnow::token::take; + /// use winnow::binary::u8; /// /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { /// let (input, length) = u8.parse_next(input)?; @@ -468,8 +481,8 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// use winnow::character::digit1; - /// use winnow::bytes::take; + /// use winnow::ascii::digit1; + /// use winnow::token::take; /// # fn main() { /// /// let mut digits = take(5u8).and_then(digit1); @@ -495,7 +508,7 @@ pub trait Parser<I, O, E> { /// ```rust /// # use winnow::prelude::*; /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; - /// use winnow::character::digit1; + /// use winnow::ascii::digit1; /// /// fn parser(input: &str) -> IResult<&str, u64> { /// digit1.parse_to().parse_next(input) @@ -527,7 +540,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; - /// # use winnow::character::alpha1; + /// # use winnow::ascii::alpha1; /// # fn main() { /// /// let mut parser = alpha1.verify(|s: &str| s.len() == 4); @@ -572,7 +585,7 @@ pub trait Parser<I, O, E> { /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, stream::Partial, Parser}; - /// # use winnow::bytes::take; + /// # use winnow::token::take; /// # fn main() { /// /// let mut parser = take(5u8).complete_err(); @@ -602,12 +615,13 @@ impl<'a, I, O, E, F> Parser<I, O, E> for F where F: FnMut(I) -> IResult<I, O, E> + 'a, { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, O, E> { self(i) } } -/// This is a shortcut for [`one_of`][crate::bytes::one_of]. +/// This is a shortcut for [`one_of`][crate::token::one_of]. /// /// # Example /// @@ -628,12 +642,13 @@ where I: Stream<Token = u8>, E: ParseError<I>, { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, u8, E> { - crate::bytes::one_of(*self).parse_next(i) + crate::token::one_of(*self).parse_next(i) } } -/// This is a shortcut for [`one_of`][crate::bytes::one_of]. +/// This is a shortcut for [`one_of`][crate::token::one_of]. /// /// # Example /// @@ -655,19 +670,20 @@ where <I as Stream>::Token: AsChar + Copy, E: ParseError<I>, { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Token, E> { - crate::bytes::one_of(*self).parse_next(i) + crate::token::one_of(*self).parse_next(i) } } -/// This is a shortcut for [`tag`][crate::bytes::tag]. +/// This is a shortcut for [`tag`][crate::token::tag]. /// /// # Example /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; -/// # use winnow::branch::alt; -/// # use winnow::bytes::take; +/// # use winnow::combinator::alt; +/// # use winnow::token::take; /// /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { /// alt((&"Hello"[..], take(5usize))).parse_next(s) @@ -683,19 +699,20 @@ where I: Compare<&'s [u8]> + StreamIsPartial, I: Stream, { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { - crate::bytes::tag(*self).parse_next(i) + crate::token::tag(*self).parse_next(i) } } -/// This is a shortcut for [`tag`][crate::bytes::tag]. +/// This is a shortcut for [`tag`][crate::token::tag]. /// /// # Example /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; -/// # use winnow::branch::alt; -/// # use winnow::bytes::take; +/// # use winnow::combinator::alt; +/// # use winnow::token::take; /// /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { /// alt((b"Hello", take(5usize))).parse_next(s) @@ -711,19 +728,20 @@ 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> { - crate::bytes::tag(*self).parse_next(i) + crate::token::tag(*self).parse_next(i) } } -/// This is a shortcut for [`tag`][crate::bytes::tag]. +/// This is a shortcut for [`tag`][crate::token::tag]. /// /// # Example /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}}; -/// # use winnow::branch::alt; -/// # use winnow::bytes::take; +/// # use winnow::combinator::alt; +/// # use winnow::token::take; /// /// fn parser(s: &str) -> IResult<&str, &str> { /// alt(("Hello", take(5usize))).parse_next(s) @@ -739,12 +757,14 @@ where I: Compare<&'s str> + StreamIsPartial, I: Stream, { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { - crate::bytes::tag(*self).parse_next(i) + crate::token::tag(*self).parse_next(i) } } impl<I, E: ParseError<I>> Parser<I, (), E> for () { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, (), E> { Ok((i, ())) } @@ -757,6 +777,7 @@ macro_rules! impl_parser_for_tuple { where $($parser: Parser<I, $output, E>),+ { + #[inline(always)] fn parse_next(&mut self, i: I) -> IResult<I, ($($output),+,), E> { let ($(ref mut $parser),+,) = *self; @@ -810,6 +831,7 @@ 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) } @@ -818,12 +840,12 @@ impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> { #[cfg(test)] mod tests { use super::*; - use crate::bytes::take; + use crate::binary::be_u16; use crate::error::ErrMode; use crate::error::Error; use crate::error::ErrorKind; use crate::error::Needed; - use crate::number::be_u16; + use crate::token::take; use crate::Partial; #[doc(hidden)] @@ -852,7 +874,7 @@ mod tests { #[test] fn single_element_tuples() { - use crate::character::alpha1; + use crate::ascii::alpha1; use crate::error::ErrorKind; let mut parser = (alpha1,); diff --git a/vendor/winnow/src/sequence.rs b/vendor/winnow/src/sequence.rs new file mode 100644 index 000000000..2d7af28e9 --- /dev/null +++ b/vendor/winnow/src/sequence.rs @@ -0,0 +1,9 @@ +//! Deprecated, see [`combinator`] +#![deprecated(since = "0.4.2", note = "Replaced with `combinator`")] + +use crate::combinator; + +pub use combinator::delimited; +pub use combinator::preceded; +pub use combinator::separated_pair; +pub use combinator::terminated; diff --git a/vendor/winnow/src/sequence/tests.rs b/vendor/winnow/src/sequence/tests.rs deleted file mode 100644 index 77fa75df6..000000000 --- a/vendor/winnow/src/sequence/tests.rs +++ /dev/null @@ -1,211 +0,0 @@ -use super::*; - -use crate::error::{ErrMode, ErrorKind, Needed}; -use crate::IResult; -use crate::Partial; - -#[derive(PartialEq, Eq, Debug)] -struct B { - a: u8, - b: u8, -} - -#[derive(PartialEq, Eq, Debug)] -struct C { - a: u8, - b: Option<u8>, -} - -#[test] -fn complete() { - fn err_test(i: &[u8]) -> IResult<&[u8], &[u8]> { - let (i, _) = "ijkl".parse_next(i)?; - "mnop".parse_next(i) - } - let a = &b"ijklmn"[..]; - - let res_a = err_test(a); - assert_eq!( - res_a, - Err(ErrMode::Backtrack(error_position!( - &b"mn"[..], - ErrorKind::Tag - ))) - ); -} - -#[test] -fn separated_pair_test() { - #[allow(clippy::type_complexity)] - fn sep_pair_abc_def(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (&[u8], &[u8])> { - separated_pair("abc", ",", "def").parse_next(i) - } - - assert_eq!( - sep_pair_abc_def(Partial::new(&b"abc,defghijkl"[..])), - Ok((Partial::new(&b"ghijkl"[..]), (&b"abc"[..], &b"def"[..]))) - ); - assert_eq!( - sep_pair_abc_def(Partial::new(&b"ab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - sep_pair_abc_def(Partial::new(&b"abc,d"[..])), - Err(ErrMode::Incomplete(Needed::new(2))) - ); - assert_eq!( - sep_pair_abc_def(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - sep_pair_abc_def(Partial::new(&b"xxx,def"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx,def"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - sep_pair_abc_def(Partial::new(&b"abc,xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); -} - -#[test] -fn preceded_test() { - fn preceded_abcd_efgh(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - preceded("abcd", "efgh").parse_next(i) - } - - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"abcdefghijkl"[..])), - Ok((Partial::new(&b"ijkl"[..]), &b"efgh"[..])) - ); - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"ab"[..])), - Err(ErrMode::Incomplete(Needed::new(2))) - ); - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"abcde"[..])), - Err(ErrMode::Incomplete(Needed::new(3))) - ); - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"xxxxdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxxdef"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - preceded_abcd_efgh(Partial::new(&b"abcdxxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); -} - -#[test] -fn terminated_test() { - fn terminated_abcd_efgh(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - terminated("abcd", "efgh").parse_next(i) - } - - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"abcdefghijkl"[..])), - Ok((Partial::new(&b"ijkl"[..]), &b"abcd"[..])) - ); - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"ab"[..])), - Err(ErrMode::Incomplete(Needed::new(2))) - ); - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"abcde"[..])), - Err(ErrMode::Incomplete(Needed::new(3))) - ); - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"xxxxdef"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxxdef"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - terminated_abcd_efgh(Partial::new(&b"abcdxxxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxx"[..]), - ErrorKind::Tag - ))) - ); -} - -#[test] -fn delimited_test() { - fn delimited_abc_def_ghi(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - delimited("abc", "def", "ghi").parse_next(i) - } - - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"abcdefghijkl"[..])), - Ok((Partial::new(&b"jkl"[..]), &b"def"[..])) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"ab"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"abcde"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"abcdefgh"[..])), - Err(ErrMode::Incomplete(Needed::new(1))) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"xxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"xxxdefghi"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxdefghi"[..]), - ErrorKind::Tag - ),)) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"abcxxxghi"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxxghi"[..]), - ErrorKind::Tag - ))) - ); - assert_eq!( - delimited_abc_def_ghi(Partial::new(&b"abcdefxxx"[..])), - Err(ErrMode::Backtrack(error_position!( - Partial::new(&b"xxx"[..]), - ErrorKind::Tag - ))) - ); -} diff --git a/vendor/winnow/src/stream/mod.rs b/vendor/winnow/src/stream/mod.rs index 019975a72..3d7a41e09 100644 --- a/vendor/winnow/src/stream/mod.rs +++ b/vendor/winnow/src/stream/mod.rs @@ -13,9 +13,6 @@ use core::num::NonZeroUsize; use crate::error::{ErrMode, ErrorKind, Needed, ParseError}; use crate::lib::std::iter::{Cloned, Enumerate}; -use crate::lib::std::ops::{ - Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, -}; use crate::lib::std::slice::Iter; use crate::lib::std::str::from_utf8; use crate::lib::std::str::CharIndices; @@ -145,7 +142,7 @@ impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Located /// # use std::cell::Cell; /// # use winnow::prelude::*; /// # use winnow::stream::Stateful; -/// # use winnow::character::alpha1; +/// # use winnow::ascii::alpha1; /// # type Error = (); /// /// #[derive(Clone, Debug)] @@ -221,15 +218,15 @@ impl<I: crate::lib::std::fmt::Display, S> crate::lib::std::fmt::Display for Stat /// Here is how it works in practice: /// /// ```rust -/// # use winnow::{IResult, error::ErrMode, error::Needed, error::{Error, ErrorKind}, bytes, character, stream::Partial}; +/// # use winnow::{IResult, error::ErrMode, error::Needed, error::{Error, ErrorKind}, token, ascii, stream::Partial}; /// # use winnow::prelude::*; /// /// fn take_partial(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { -/// bytes::take(4u8).parse_next(i) +/// token::take(4u8).parse_next(i) /// } /// /// fn take_complete(i: &[u8]) -> IResult<&[u8], &[u8]> { -/// bytes::take(4u8).parse_next(i) +/// token::take(4u8).parse_next(i) /// } /// /// // both parsers will take 4 bytes as expected @@ -245,11 +242,11 @@ impl<I: crate::lib::std::fmt::Display, S> crate::lib::std::fmt::Display for Stat /// /// // the alpha0 function recognizes 0 or more alphabetic characters /// fn alpha0_partial(i: Partial<&str>) -> IResult<Partial<&str>, &str> { -/// character::alpha0(i) +/// ascii::alpha0(i) /// } /// /// fn alpha0_complete(i: &str) -> IResult<&str, &str> { -/// character::alpha0(i) +/// ascii::alpha0(i) /// } /// /// // if there's a clear limit to the recognized characters, both parsers work the same way @@ -708,7 +705,7 @@ where } } -/// Iterator for [bit][crate::bits] stream (`(I, usize)`) +/// Iterator for [bit][crate::binary::bits] stream (`(I, usize)`) pub struct BitOffsets<I> { i: (I, usize), o: usize, @@ -1747,6 +1744,123 @@ where } } +/// A range bounded inclusively for counting parses performed +#[derive(PartialEq, Eq)] +pub struct Range { + pub(crate) start_inclusive: usize, + pub(crate) end_inclusive: Option<usize>, +} + +impl Range { + #[inline(always)] + fn raw(start_inclusive: usize, end_inclusive: Option<usize>) -> Self { + Self { + start_inclusive, + end_inclusive, + } + } +} + +impl crate::lib::std::ops::RangeBounds<usize> for Range { + #[inline(always)] + fn start_bound(&self) -> crate::lib::std::ops::Bound<&usize> { + crate::lib::std::ops::Bound::Included(&self.start_inclusive) + } + + #[inline(always)] + fn end_bound(&self) -> crate::lib::std::ops::Bound<&usize> { + if let Some(end_inclusive) = &self.end_inclusive { + crate::lib::std::ops::Bound::Included(end_inclusive) + } else { + crate::lib::std::ops::Bound::Unbounded + } + } +} + +impl From<usize> for Range { + #[inline(always)] + fn from(fixed: usize) -> Self { + (fixed..=fixed).into() + } +} + +impl From<crate::lib::std::ops::Range<usize>> for Range { + #[inline(always)] + fn from(range: crate::lib::std::ops::Range<usize>) -> Self { + let start_inclusive = range.start; + let end_inclusive = Some(range.end.saturating_sub(1)); + Self::raw(start_inclusive, end_inclusive) + } +} + +impl From<crate::lib::std::ops::RangeFull> for Range { + #[inline(always)] + fn from(_: crate::lib::std::ops::RangeFull) -> Self { + let start_inclusive = 0; + let end_inclusive = None; + Self::raw(start_inclusive, end_inclusive) + } +} + +impl From<crate::lib::std::ops::RangeFrom<usize>> for Range { + #[inline(always)] + fn from(range: crate::lib::std::ops::RangeFrom<usize>) -> Self { + let start_inclusive = range.start; + let end_inclusive = None; + Self::raw(start_inclusive, end_inclusive) + } +} + +impl From<crate::lib::std::ops::RangeTo<usize>> for Range { + #[inline(always)] + fn from(range: crate::lib::std::ops::RangeTo<usize>) -> Self { + let start_inclusive = 0; + let end_inclusive = Some(range.end.saturating_sub(1)); + Self::raw(start_inclusive, end_inclusive) + } +} + +impl From<crate::lib::std::ops::RangeInclusive<usize>> for Range { + #[inline(always)] + fn from(range: crate::lib::std::ops::RangeInclusive<usize>) -> Self { + let start_inclusive = *range.start(); + let end_inclusive = Some(*range.end()); + Self::raw(start_inclusive, end_inclusive) + } +} + +impl From<crate::lib::std::ops::RangeToInclusive<usize>> for Range { + #[inline(always)] + fn from(range: crate::lib::std::ops::RangeToInclusive<usize>) -> Self { + let start_inclusive = 0; + let end_inclusive = Some(range.end); + Self::raw(start_inclusive, end_inclusive) + } +} + +impl crate::lib::std::fmt::Display for Range { + fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { + self.start_inclusive.fmt(f)?; + match self.end_inclusive { + Some(e) if e == self.start_inclusive => {} + Some(e) => { + "..=".fmt(f)?; + e.fmt(f)?; + } + None => { + "..".fmt(f)?; + } + } + Ok(()) + } +} + +impl crate::lib::std::fmt::Debug for Range { + fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result { + write!(f, "{self}") + } +} + /// Abstracts something which can extend an `Extend`. /// Used to build modified input slices in `escaped_transform` pub trait Accumulate<T>: Sized { @@ -2006,6 +2120,7 @@ impl AsChar for u8 { fn is_space(self) -> bool { self == b' ' || self == b'\t' } + #[inline] fn is_newline(self) -> bool { self == b'\n' } @@ -2043,6 +2158,7 @@ impl<'a> AsChar for &'a u8 { fn is_space(self) -> bool { *self == b' ' || *self == b'\t' } + #[inline] fn is_newline(self) -> bool { *self == b'\n' } @@ -2081,6 +2197,7 @@ impl AsChar for char { fn is_space(self) -> bool { self == ' ' || self == '\t' } + #[inline] fn is_newline(self) -> bool { self == '\n' } @@ -2119,6 +2236,7 @@ impl<'a> AsChar for &'a char { fn is_space(self) -> bool { *self == ' ' || *self == '\t' } + #[inline] fn is_newline(self) -> bool { *self == '\n' } @@ -2140,9 +2258,9 @@ impl<'a> AsChar for &'a char { /// ``` /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::bytes::take_while1; +/// # use winnow::token::take_while; /// fn hex_digit1(input: &str) -> IResult<&str, &str> { -/// take_while1(('a'..='f', 'A'..='F', '0'..='9')).parse_next(input) +/// take_while(1.., ('a'..='f', 'A'..='F', '0'..='9')).parse_next(input) /// } /// /// assert_eq!(hex_digit1("21cZ"), Ok(("Z", "21c"))); @@ -2196,7 +2314,7 @@ impl<C: AsChar, F: Fn(C) -> bool> ContainsToken<C> for F { } } -impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for Range<C2> { +impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::Range<C2> { #[inline(always)] fn contains_token(&self, token: C1) -> bool { let start = self.start.clone().as_char(); @@ -2205,7 +2323,9 @@ impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for Range<C2> { } } -impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeInclusive<C2> { +impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> + for crate::lib::std::ops::RangeInclusive<C2> +{ #[inline(always)] fn contains_token(&self, token: C1) -> bool { let start = self.start().clone().as_char(); @@ -2214,7 +2334,7 @@ impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeInclusive<C2> { } } -impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeFrom<C2> { +impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeFrom<C2> { #[inline(always)] fn contains_token(&self, token: C1) -> bool { let start = self.start.clone().as_char(); @@ -2222,7 +2342,7 @@ impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeFrom<C2> { } } -impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeTo<C2> { +impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeTo<C2> { #[inline(always)] fn contains_token(&self, token: C1) -> bool { let end = self.end.clone().as_char(); @@ -2230,7 +2350,9 @@ impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeTo<C2> { } } -impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeToInclusive<C2> { +impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> + for crate::lib::std::ops::RangeToInclusive<C2> +{ #[inline(always)] fn contains_token(&self, token: C1) -> bool { let end = self.end.clone().as_char(); @@ -2238,7 +2360,7 @@ impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for RangeToInclusive<C2> } } -impl<C1: AsChar> ContainsToken<C1> for RangeFull { +impl<C1: AsChar> ContainsToken<C1> for crate::lib::std::ops::RangeFull { #[inline(always)] fn contains_token(&self, _token: C1) -> bool { true diff --git a/vendor/winnow/src/bytes/mod.rs b/vendor/winnow/src/token/mod.rs index 0bf8681b7..6f99dfa8d 100644 --- a/vendor/winnow/src/bytes/mod.rs +++ b/vendor/winnow/src/token/mod.rs @@ -1,4 +1,4 @@ -//! Parsers recognizing bytes streams +//! Parsers extracting tokens from the stream #[cfg(test)] mod tests; @@ -8,6 +8,7 @@ use crate::error::ErrorKind; use crate::error::Needed; use crate::error::ParseError; use crate::lib::std::result::Result::Ok; +use crate::stream::Range; use crate::stream::{ split_at_offset1_complete, split_at_offset1_partial, split_at_offset_complete, split_at_offset_partial, Compare, CompareResult, ContainsToken, FindSlice, SliceLen, Stream, @@ -26,7 +27,7 @@ use crate::Parser; /// # Example /// /// ```rust -/// # use winnow::{bytes::any, error::ErrMode, error::{Error, ErrorKind}}; +/// # use winnow::{token::any, error::ErrMode, error::{Error, ErrorKind}}; /// # use winnow::prelude::*; /// fn parser(input: &str) -> IResult<&str, char> { /// any.parse_next(input) @@ -37,7 +38,7 @@ use crate::Parser; /// ``` /// /// ```rust -/// # use winnow::{bytes::any, error::ErrMode, error::ErrorKind, error::Error, error::Needed}; +/// # use winnow::{token::any, error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; /// assert_eq!(any::<_, Error<_>>.parse_next(Partial::new("abc")), Ok((Partial::new("bc"),'a'))); @@ -51,31 +52,27 @@ where I: Stream, { trace("any", move |input: I| { - if input.is_partial() { - streaming_any(input) + if <I as StreamIsPartial>::is_partial_supported() { + any_::<_, _, true>(input) } else { - complete_any(input) + any_::<_, _, true>(input) } }) .parse_next(input) } -pub(crate) fn streaming_any<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Token, E> -where - I: Stream, -{ - input - .next_token() - .ok_or_else(|| ErrMode::Incomplete(Needed::new(1))) -} - -pub(crate) fn complete_any<I, E: ParseError<I>>(input: I) -> IResult<I, <I as Stream>::Token, E> +fn any_<I, E: ParseError<I>, const PARTIAL: bool>(input: I) -> IResult<I, <I as Stream>::Token, E> where + I: StreamIsPartial, I: Stream, { - input - .next_token() - .ok_or_else(|| ErrMode::from_error_kind(input, ErrorKind::Token)) + input.next_token().ok_or_else(|| { + if PARTIAL && input.is_partial() { + ErrMode::Incomplete(Needed::new(1)) + } else { + ErrMode::from_error_kind(input, ErrorKind::Token) + } + }) } /// Recognizes a literal @@ -92,7 +89,7 @@ where /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; -/// use winnow::bytes::tag; +/// use winnow::token::tag; /// /// fn parser(s: &str) -> IResult<&str, &str> { /// "Hello".parse_next(s) @@ -107,7 +104,7 @@ where /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::Partial; -/// use winnow::bytes::tag; +/// use winnow::token::tag; /// /// fn parser(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// "Hello".parse_next(s) @@ -130,46 +127,29 @@ where { trace("tag", move |i: I| { let t = tag.clone(); - if i.is_partial() { - streaming_tag_internal(i, t) + if <I as StreamIsPartial>::is_partial_supported() { + tag_::<_, _, _, true>(i, t) } else { - complete_tag_internal(i, t) + tag_::<_, _, _, false>(i, t) } }) } -pub(crate) fn streaming_tag_internal<T, I, Error: ParseError<I>>( +fn tag_<T, I, Error: ParseError<I>, const PARTIAL: bool>( i: I, t: T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + Compare<T>, T: SliceLen, { let tag_len = t.slice_len(); match i.compare(t) { CompareResult::Ok => Ok(i.next_slice(tag_len)), - CompareResult::Incomplete => { + CompareResult::Incomplete if PARTIAL && i.is_partial() => { Err(ErrMode::Incomplete(Needed::new(tag_len - i.eof_offset()))) } - CompareResult::Error => { - let e: ErrorKind = ErrorKind::Tag; - Err(ErrMode::from_error_kind(i, e)) - } - } -} - -pub(crate) fn complete_tag_internal<T, I, Error: ParseError<I>>( - i: I, - t: T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream + Compare<T>, - T: SliceLen, -{ - let tag_len = t.slice_len(); - match i.compare(t) { - CompareResult::Ok => Ok(i.next_slice(tag_len)), CompareResult::Incomplete | CompareResult::Error => { let e: ErrorKind = ErrorKind::Tag; Err(ErrMode::from_error_kind(i, e)) @@ -189,7 +169,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::tag_no_case; +/// use winnow::token::tag_no_case; /// /// fn parser(s: &str) -> IResult<&str, &str> { /// tag_no_case("hello").parse_next(s) @@ -206,7 +186,7 @@ where /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::tag_no_case; +/// use winnow::token::tag_no_case; /// /// fn parser(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// tag_no_case("hello").parse_next(s) @@ -232,19 +212,20 @@ where { trace("tag_no_case", move |i: I| { let t = tag.clone(); - if i.is_partial() { - streaming_tag_no_case_internal(i, t) + if <I as StreamIsPartial>::is_partial_supported() { + tag_no_case_::<_, _, _, true>(i, t) } else { - complete_tag_no_case_internal(i, t) + tag_no_case_::<_, _, _, false>(i, t) } }) } -pub(crate) fn streaming_tag_no_case_internal<T, I, Error: ParseError<I>>( +fn tag_no_case_<T, I, Error: ParseError<I>, const PARTIAL: bool>( i: I, t: T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + Compare<T>, T: SliceLen, { @@ -252,28 +233,9 @@ where match (i).compare_no_case(t) { CompareResult::Ok => Ok(i.next_slice(tag_len)), - CompareResult::Incomplete => { + CompareResult::Incomplete if PARTIAL && i.is_partial() => { Err(ErrMode::Incomplete(Needed::new(tag_len - i.eof_offset()))) } - CompareResult::Error => { - let e: ErrorKind = ErrorKind::Tag; - Err(ErrMode::from_error_kind(i, e)) - } - } -} - -pub(crate) fn complete_tag_no_case_internal<T, I, Error: ParseError<I>>( - i: I, - t: T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream + Compare<T>, - T: SliceLen, -{ - let tag_len = t.slice_len(); - - match (i).compare_no_case(t) { - CompareResult::Ok => Ok(i.next_slice(tag_len)), CompareResult::Incomplete | CompareResult::Error => { let e: ErrorKind = ErrorKind::Tag; Err(ErrMode::from_error_kind(i, e)) @@ -297,7 +259,7 @@ where /// ```rust /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; -/// # use winnow::bytes::one_of; +/// # use winnow::token::one_of; /// assert_eq!(one_of::<_, _, Error<_>>("abc").parse_next("b"), Ok(("", 'b'))); /// assert_eq!(one_of::<_, _, Error<_>>("a").parse_next("bc"), Err(ErrMode::Backtrack(Error::new("bc", ErrorKind::Verify)))); /// assert_eq!(one_of::<_, _, Error<_>>("a").parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Token)))); @@ -314,7 +276,7 @@ where /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::Partial; -/// # use winnow::bytes::one_of; +/// # use winnow::token::one_of; /// assert_eq!(one_of::<_, _, Error<_>>("abc").parse_next(Partial::new("b")), Ok((Partial::new(""), 'b'))); /// assert_eq!(one_of::<_, _, Error<_>>("a").parse_next(Partial::new("bc")), Err(ErrMode::Backtrack(Error::new(Partial::new("bc"), ErrorKind::Verify)))); /// assert_eq!(one_of::<_, _, Error<_>>("a").parse_next(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -354,7 +316,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error}; /// # use winnow::prelude::*; -/// # use winnow::bytes::none_of; +/// # use winnow::token::none_of; /// assert_eq!(none_of::<_, _, Error<_>>("abc").parse_next("z"), Ok(("", 'z'))); /// assert_eq!(none_of::<_, _, Error<_>>("ab").parse_next("a"), Err(ErrMode::Backtrack(Error::new("a", ErrorKind::Verify)))); /// assert_eq!(none_of::<_, _, Error<_>>("a").parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Token)))); @@ -364,7 +326,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// # use winnow::bytes::none_of; +/// # use winnow::token::none_of; /// assert_eq!(none_of::<_, _, Error<_>>("abc").parse_next(Partial::new("z")), Ok((Partial::new(""), 'z'))); /// assert_eq!(none_of::<_, _, Error<_>>("ab").parse_next(Partial::new("a")), Err(ErrMode::Backtrack(Error::new(Partial::new("a"), ErrorKind::Verify)))); /// assert_eq!(none_of::<_, _, Error<_>>("a").parse_next(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); @@ -383,22 +345,26 @@ where ) } -/// Recognize the longest input slice (if any) that matches the [pattern][ContainsToken] +/// Recognize the longest (m <= len <= n) input slice that matches the [pattern][ContainsToken] +/// +/// It will return an `ErrMode::Backtrack(Error::new(_, ErrorKind::Slice))` if the pattern wasn't met or is out +/// of range (m <= len <= n). /// -/// *Partial version*: will return a `ErrMode::Incomplete(Needed::new(1))` if the pattern reaches the end of the input. +/// *Partial version* will return a `ErrMode::Incomplete(Needed::new(1))` if the pattern reaches the end of the input or is too short. /// -/// To recognize a series of tokens, use [`many0`][crate::multi::many0] to [`Accumulate`][crate::stream::Accumulate] into a `()` and then [`Parser::recognize`][crate::Parser::recognize]. +/// To recognize a series of tokens, use [`repeat`][crate::combinator::repeat] to [`Accumulate`][crate::stream::Accumulate] into a `()` and then [`Parser::recognize`][crate::Parser::recognize]. /// /// # Example /// +/// Zero or more tokens: /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_while0; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { -/// take_while0(AsChar::is_alpha).parse_next(s) +/// take_while(0.., AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); @@ -411,11 +377,11 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_while0; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn alpha(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { -/// take_while0(AsChar::is_alpha).parse_next(s) +/// take_while(0.., AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(alpha(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..]))); @@ -423,64 +389,16 @@ where /// assert_eq!(alpha(Partial::new(b"latin")), Err(ErrMode::Incomplete(Needed::new(1)))); /// assert_eq!(alpha(Partial::new(b"")), Err(ErrMode::Incomplete(Needed::new(1)))); /// ``` -#[inline(always)] -pub fn take_while0<T, I, Error: ParseError<I>>( - list: T, -) -> impl Parser<I, <I as Stream>::Slice, Error> -where - I: StreamIsPartial, - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - trace("take_while0", move |i: I| { - if i.is_partial() { - streaming_take_while_internal(i, &list) - } else { - complete_take_while_internal(i, &list) - } - }) -} - -pub(crate) fn streaming_take_while_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - split_at_offset_partial(&i, |c| !list.contains_token(c)) -} - -pub(crate) fn complete_take_while_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - split_at_offset_complete(&i, |c| !list.contains_token(c)) -} - -/// Recognize the longest (at least 1) input slice that matches the [pattern][ContainsToken] -/// -/// It will return an `Err(ErrMode::Backtrack(Error::new(_, ErrorKind::Slice)))` if the pattern wasn't met. -/// -/// *Partial version* will return a `ErrMode::Incomplete(Needed::new(1))` or if the pattern reaches the end of the input. -/// -/// To recognize a series of tokens, use [`many1`][crate::multi::many1] to [`Accumulate`][crate::stream::Accumulate] into a `()` and then [`Parser::recognize`][crate::Parser::recognize]. -/// -/// # Example /// +/// One or more tokens: /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_while1; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { -/// take_while1(AsChar::is_alpha).parse_next(s) +/// take_while(1.., AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); @@ -488,7 +406,7 @@ where /// assert_eq!(alpha(b"12345"), Err(ErrMode::Backtrack(Error::new(&b"12345"[..], ErrorKind::Slice)))); /// /// fn hex(s: &str) -> IResult<&str, &str> { -/// take_while1("1234567890ABCDEF").parse_next(s) +/// take_while(1.., "1234567890ABCDEF").parse_next(s) /// } /// /// assert_eq!(hex("123 and voila"), Ok((" and voila", "123"))); @@ -502,11 +420,11 @@ where /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_while1; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn alpha(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { -/// take_while1(AsChar::is_alpha).parse_next(s) +/// take_while(1.., AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(alpha(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..]))); @@ -514,7 +432,7 @@ where /// assert_eq!(alpha(Partial::new(b"12345")), Err(ErrMode::Backtrack(Error::new(Partial::new(&b"12345"[..]), ErrorKind::Slice)))); /// /// fn hex(s: Partial<&str>) -> IResult<Partial<&str>, &str> { -/// take_while1("1234567890ABCDEF").parse_next(s) +/// take_while(1.., "1234567890ABCDEF").parse_next(s) /// } /// /// assert_eq!(hex(Partial::new("123 and voila")), Ok((Partial::new(" and voila"), "123"))); @@ -523,68 +441,16 @@ where /// assert_eq!(hex(Partial::new("D15EA5E")), Err(ErrMode::Incomplete(Needed::new(1)))); /// assert_eq!(hex(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); /// ``` -#[inline(always)] -#[doc(alias = "is_a")] -pub fn take_while1<T, I, Error: ParseError<I>>( - list: T, -) -> impl Parser<I, <I as Stream>::Slice, Error> -where - I: StreamIsPartial, - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - trace("take_while1", move |i: I| { - if i.is_partial() { - streaming_take_while1_internal(i, &list) - } else { - complete_take_while1_internal(i, &list) - } - }) -} - -pub(crate) fn streaming_take_while1_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - let e: ErrorKind = ErrorKind::Slice; - split_at_offset1_partial(&i, |c| !list.contains_token(c), e) -} - -pub(crate) fn complete_take_while1_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - let e: ErrorKind = ErrorKind::Slice; - split_at_offset1_complete(&i, |c| !list.contains_token(c), e) -} - -/// Recognize the longest (m <= len <= n) input slice that matches the [pattern][ContainsToken] -/// -/// It will return an `ErrMode::Backtrack(Error::new(_, ErrorKind::Slice))` if the pattern wasn't met or is out -/// of range (m <= len <= n). -/// -/// *Partial version* will return a `ErrMode::Incomplete(Needed::new(1))` if the pattern reaches the end of the input or is too short. -/// -/// To recognize a series of tokens, use [`many_m_n`][crate::multi::many_m_n] to [`Accumulate`][crate::stream::Accumulate] into a `()` and then [`Parser::recognize`][crate::Parser::recognize]. -/// -/// # Example /// +/// Arbitrary amount of tokens: /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_while_m_n; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { -/// take_while_m_n(3, 6, AsChar::is_alpha).parse_next(s) +/// take_while(3..=6, AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..]))); @@ -598,11 +464,11 @@ where /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_while_m_n; +/// use winnow::token::take_while; /// use winnow::stream::AsChar; /// /// fn short_alpha(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { -/// take_while_m_n(3, 6, AsChar::is_alpha).parse_next(s) +/// take_while(3..=6, AsChar::is_alpha).parse_next(s) /// } /// /// assert_eq!(short_alpha(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..]))); @@ -612,9 +478,11 @@ where /// assert_eq!(short_alpha(Partial::new(b"12345")), Err(ErrMode::Backtrack(Error::new(Partial::new(&b"12345"[..]), ErrorKind::Slice)))); /// ``` #[inline(always)] -pub fn take_while_m_n<T, I, Error: ParseError<I>>( - m: usize, - n: usize, +#[doc(alias = "is_a")] +#[doc(alias = "take_while0")] +#[doc(alias = "take_while1")] +pub fn take_while<T, I, Error: ParseError<I>>( + range: impl Into<Range>, list: T, ) -> impl Parser<I, <I as Stream>::Slice, Error> where @@ -622,64 +490,107 @@ where I: Stream, T: ContainsToken<<I as Stream>::Token>, { - trace("take_while_m_n", move |i: I| { - if i.is_partial() { - streaming_take_while_m_n_internal(i, m, n, &list) - } else { - complete_take_while_m_n_internal(i, m, n, &list) + let Range { + start_inclusive, + end_inclusive, + } = range.into(); + trace("take_while", move |i: I| { + match (start_inclusive, end_inclusive) { + (0, None) => { + if <I as StreamIsPartial>::is_partial_supported() { + take_while0_::<_, _, _, true>(i, &list) + } else { + take_while0_::<_, _, _, false>(i, &list) + } + } + (1, None) => { + if <I as StreamIsPartial>::is_partial_supported() { + take_while1_::<_, _, _, true>(i, &list) + } else { + take_while1_::<_, _, _, false>(i, &list) + } + } + (start, end) => { + let end = end.unwrap_or(usize::MAX); + if <I as StreamIsPartial>::is_partial_supported() { + take_while_m_n_::<_, _, _, true>(i, start, end, &list) + } else { + take_while_m_n_::<_, _, _, false>(i, start, end, &list) + } + } } }) } -pub(crate) fn streaming_take_while_m_n_internal<T, I, Error: ParseError<I>>( +/// Deprecated, see [`take_while`] +#[deprecated(since = "0.4.6", note = "Replaced with `take_while`")] +#[inline(always)] +pub fn take_while0<T, I, Error: ParseError<I>>( + list: T, +) -> impl Parser<I, <I as Stream>::Slice, Error> +where + I: StreamIsPartial, + I: Stream, + T: ContainsToken<<I as Stream>::Token>, +{ + take_while(0.., list) +} + +/// Deprecated, see [`take_while`] +#[deprecated(since = "0.4.6", note = "Replaced with `take_while`")] +#[inline(always)] +pub fn take_while1<T, I, Error: ParseError<I>>( + list: T, +) -> impl Parser<I, <I as Stream>::Slice, Error> +where + I: StreamIsPartial, + I: Stream, + T: ContainsToken<<I as Stream>::Token>, +{ + take_while(1.., list) +} + +fn take_while0_<T, I, Error: ParseError<I>, const PARTIAL: bool>( input: I, - m: usize, - n: usize, list: &T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream, T: ContainsToken<<I as Stream>::Token>, { - if n < m { - return Err(ErrMode::assert(input, "`m` should be <= `n`")); - } - - let mut final_count = 0; - for (processed, (offset, token)) in input.iter_offsets().enumerate() { - if !list.contains_token(token) { - if processed < m { - return Err(ErrMode::from_error_kind(input, ErrorKind::Slice)); - } else { - return Ok(input.next_slice(offset)); - } - } else { - if processed == n { - return Ok(input.next_slice(offset)); - } - final_count = processed + 1; - } + if PARTIAL && input.is_partial() { + split_at_offset_partial(&input, |c| !list.contains_token(c)) + } else { + split_at_offset_complete(&input, |c| !list.contains_token(c)) } +} - if final_count == n { - Ok(input.next_slice(input.eof_offset())) +fn take_while1_<T, I, Error: ParseError<I>, const PARTIAL: bool>( + input: I, + list: &T, +) -> IResult<I, <I as Stream>::Slice, Error> +where + I: StreamIsPartial, + I: Stream, + T: ContainsToken<<I as Stream>::Token>, +{ + let e: ErrorKind = ErrorKind::Slice; + if PARTIAL && input.is_partial() { + split_at_offset1_partial(&input, |c| !list.contains_token(c), e) } else { - let needed = if m > input.eof_offset() { - m - input.eof_offset() - } else { - 1 - }; - Err(ErrMode::Incomplete(Needed::new(needed))) + split_at_offset1_complete(&input, |c| !list.contains_token(c), e) } } -pub(crate) fn complete_take_while_m_n_internal<T, I, Error: ParseError<I>>( +fn take_while_m_n_<T, I, Error: ParseError<I>, const PARTIAL: bool>( input: I, m: usize, n: usize, list: &T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream, T: ContainsToken<<I as Stream>::Token>, { @@ -702,11 +613,23 @@ where final_count = processed + 1; } } - - if m <= final_count { - Ok(input.next_slice(input.eof_offset())) + if PARTIAL && input.is_partial() { + if final_count == n { + Ok(input.next_slice(input.eof_offset())) + } else { + let needed = if m > input.eof_offset() { + m - input.eof_offset() + } else { + 1 + }; + Err(ErrMode::Incomplete(Needed::new(needed))) + } } else { - Err(ErrMode::from_error_kind(input, ErrorKind::Slice)) + if m <= final_count { + Ok(input.next_slice(input.eof_offset())) + } else { + Err(ErrMode::from_error_kind(input, ErrorKind::Slice)) + } } } @@ -720,7 +643,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_till0; +/// use winnow::token::take_till0; /// /// fn till_colon(s: &str) -> IResult<&str, &str> { /// take_till0(|c| c == ':').parse_next(s) @@ -736,7 +659,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_till0; +/// use winnow::token::take_till0; /// /// fn till_colon(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// take_till0(|c| c == ':').parse_next(s) @@ -757,36 +680,14 @@ where T: ContainsToken<<I as Stream>::Token>, { trace("take_till0", move |i: I| { - if i.is_partial() { - streaming_take_till_internal(i, &list) + if <I as StreamIsPartial>::is_partial_supported() && i.is_partial() { + split_at_offset_partial(&i, |c| list.contains_token(c)) } else { - complete_take_till_internal(i, &list) + split_at_offset_complete(&i, |c| list.contains_token(c)) } }) } -pub(crate) fn streaming_take_till_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - split_at_offset_partial(&i, |c| list.contains_token(c)) -} - -pub(crate) fn complete_take_till_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - split_at_offset_complete(&i, |c| list.contains_token(c)) -} - /// Recognize the longest (at least 1) input slice till a [pattern][ContainsToken] is met. /// /// It will return `Err(ErrMode::Backtrack(Error::new(_, ErrorKind::Slice)))` if the input is empty or the @@ -800,7 +701,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_till1; +/// use winnow::token::take_till1; /// /// fn till_colon(s: &str) -> IResult<&str, &str> { /// take_till1(|c| c == ':').parse_next(s) @@ -825,7 +726,7 @@ where /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_till1; +/// use winnow::token::take_till1; /// /// fn till_colon(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// take_till1(|c| c == ':').parse_next(s) @@ -856,38 +757,15 @@ where T: ContainsToken<<I as Stream>::Token>, { trace("take_till1", move |i: I| { - if i.is_partial() { - streaming_take_till1_internal(i, &list) + let e: ErrorKind = ErrorKind::Slice; + if <I as StreamIsPartial>::is_partial_supported() && i.is_partial() { + split_at_offset1_partial(&i, |c| list.contains_token(c), e) } else { - complete_take_till1_internal(i, &list) + split_at_offset1_complete(&i, |c| list.contains_token(c), e) } }) } -pub(crate) fn streaming_take_till1_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - let e: ErrorKind = ErrorKind::Slice; - split_at_offset1_partial(&i, |c| list.contains_token(c), e) -} - -pub(crate) fn complete_take_till1_internal<T, I, Error: ParseError<I>>( - i: I, - list: &T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, - T: ContainsToken<<I as Stream>::Token>, -{ - let e: ErrorKind = ErrorKind::Slice; - split_at_offset1_complete(&i, |c| list.contains_token(c), e) -} - /// Recognize an input slice containing the first N input elements (I[..N]). /// /// *Complete version*: It will return `Err(ErrMode::Backtrack(Error::new(_, ErrorKind::Slice)))` if the input is shorter than the argument. @@ -904,7 +782,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take; +/// use winnow::token::take; /// /// fn take6(s: &str) -> IResult<&str, &str> { /// take(6usize).parse_next(s) @@ -923,7 +801,7 @@ where /// ```rust /// # use winnow::prelude::*; /// use winnow::error::Error; -/// use winnow::bytes::take; +/// use winnow::token::take; /// /// assert_eq!(take::<_, _, Error<_>>(1usize).parse_next("💙"), Ok(("", "💙"))); /// assert_eq!(take::<_, _, Error<_>>(1usize).parse_next("💙".as_bytes()), Ok((b"\x9F\x92\x99".as_ref(), b"\xF0".as_ref()))); @@ -933,7 +811,7 @@ where /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::Partial; -/// use winnow::bytes::take; +/// use winnow::token::take; /// /// fn take6(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// take(6usize).parse_next(s) @@ -953,36 +831,25 @@ where { let c = count.to_usize(); trace("take", move |i: I| { - if i.is_partial() { - streaming_take_internal(i, c) + if <I as StreamIsPartial>::is_partial_supported() { + take_::<_, _, true>(i, c) } else { - complete_take_internal(i, c) + take_::<_, _, false>(i, c) } }) } -pub(crate) fn streaming_take_internal<I, Error: ParseError<I>>( - i: I, - c: usize, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream, -{ - match i.offset_at(c) { - Ok(offset) => Ok(i.next_slice(offset)), - Err(i) => Err(ErrMode::Incomplete(i)), - } -} - -pub(crate) fn complete_take_internal<I, Error: ParseError<I>>( +fn take_<I, Error: ParseError<I>, const PARTIAL: bool>( i: I, c: usize, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream, { match i.offset_at(c) { Ok(offset) => Ok(i.next_slice(offset)), + Err(e) if PARTIAL && i.is_partial() => Err(ErrMode::Incomplete(e)), Err(_needed) => Err(ErrMode::from_error_kind(i, ErrorKind::Slice)), } } @@ -1002,7 +869,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_until0; +/// use winnow::token::take_until0; /// /// fn until_eof(s: &str) -> IResult<&str, &str> { /// take_until0("eof").parse_next(s) @@ -1018,7 +885,7 @@ where /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_until0; +/// use winnow::token::take_until0; /// /// fn until_eof(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// take_until0("eof").parse_next(s) @@ -1039,38 +906,26 @@ where T: SliceLen + Clone, { trace("take_until0", move |i: I| { - if i.is_partial() { - streaming_take_until_internal(i, tag.clone()) + if <I as StreamIsPartial>::is_partial_supported() { + take_until0_::<_, _, _, true>(i, tag.clone()) } else { - complete_take_until_internal(i, tag.clone()) + take_until0_::<_, _, _, false>(i, tag.clone()) } }) } -pub(crate) fn streaming_take_until_internal<T, I, Error: ParseError<I>>( - i: I, - t: T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream + FindSlice<T>, - T: SliceLen, -{ - match i.find_slice(t) { - Some(offset) => Ok(i.next_slice(offset)), - None => Err(ErrMode::Incomplete(Needed::Unknown)), - } -} - -pub(crate) fn complete_take_until_internal<T, I, Error: ParseError<I>>( +fn take_until0_<T, I, Error: ParseError<I>, const PARTIAL: bool>( i: I, t: T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + FindSlice<T>, T: SliceLen, { match i.find_slice(t) { Some(offset) => Ok(i.next_slice(offset)), + None if PARTIAL && i.is_partial() => Err(ErrMode::Incomplete(Needed::Unknown)), None => Err(ErrMode::from_error_kind(i, ErrorKind::Slice)), } } @@ -1090,7 +945,7 @@ where /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; -/// use winnow::bytes::take_until1; +/// use winnow::token::take_until1; /// /// fn until_eof(s: &str) -> IResult<&str, &str> { /// take_until1("eof").parse_next(s) @@ -1107,7 +962,7 @@ where /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::Partial; -/// use winnow::bytes::take_until1; +/// use winnow::token::take_until1; /// /// fn until_eof(s: Partial<&str>) -> IResult<Partial<&str>, &str> { /// take_until1("eof").parse_next(s) @@ -1129,38 +984,25 @@ where T: SliceLen + Clone, { trace("take_until1", move |i: I| { - if i.is_partial() { - streaming_take_until1_internal(i, tag.clone()) + if <I as StreamIsPartial>::is_partial_supported() { + take_until1_::<_, _, _, true>(i, tag.clone()) } else { - complete_take_until1_internal(i, tag.clone()) + take_until1_::<_, _, _, false>(i, tag.clone()) } }) } -pub(crate) fn streaming_take_until1_internal<T, I, Error: ParseError<I>>( - i: I, - t: T, -) -> IResult<I, <I as Stream>::Slice, Error> -where - I: Stream + FindSlice<T>, - T: SliceLen, -{ - match i.find_slice(t) { - None => Err(ErrMode::Incomplete(Needed::Unknown)), - Some(0) => Err(ErrMode::from_error_kind(i, ErrorKind::Slice)), - Some(offset) => Ok(i.next_slice(offset)), - } -} - -pub(crate) fn complete_take_until1_internal<T, I, Error: ParseError<I>>( +fn take_until1_<T, I, Error: ParseError<I>, const PARTIAL: bool>( i: I, t: T, ) -> IResult<I, <I as Stream>::Slice, Error> where + I: StreamIsPartial, I: Stream + FindSlice<T>, T: SliceLen, { match i.find_slice(t) { + None if PARTIAL && i.is_partial() => Err(ErrMode::Incomplete(Needed::Unknown)), None | Some(0) => Err(ErrMode::from_error_kind(i, ErrorKind::Slice)), Some(offset) => Ok(i.next_slice(offset)), } diff --git a/vendor/winnow/src/bytes/tests.rs b/vendor/winnow/src/token/tests.rs index c2a1ceefd..e1c7999c2 100644 --- a/vendor/winnow/src/bytes/tests.rs +++ b/vendor/winnow/src/token/tests.rs @@ -3,14 +3,14 @@ use super::*; #[cfg(feature = "std")] use proptest::prelude::*; -use crate::bytes::tag; +use crate::binary::length_data; +use crate::combinator::delimited; use crate::error::ErrMode; use crate::error::Error; use crate::error::ErrorKind; use crate::error::Needed; -use crate::multi::length_data; -use crate::sequence::delimited; use crate::stream::AsChar; +use crate::token::tag; use crate::IResult; use crate::Parser; use crate::Partial; @@ -18,14 +18,13 @@ use crate::Partial; #[test] fn complete_take_while_m_n_utf8_all_matching() { let result: IResult<&str, &str> = - take_while_m_n(1, 4, |c: char| c.is_alphabetic()).parse_next("øn"); + take_while(1..=4, |c: char| c.is_alphabetic()).parse_next("øn"); assert_eq!(result, Ok(("", "øn"))); } #[test] fn complete_take_while_m_n_utf8_all_matching_substring() { - let result: IResult<&str, &str> = - take_while_m_n(1, 1, |c: char| c.is_alphabetic()).parse_next("øn"); + let result: IResult<&str, &str> = take_while(1, |c: char| c.is_alphabetic()).parse_next("øn"); assert_eq!(result, Ok(("n", "ø"))); } @@ -60,7 +59,7 @@ proptest! { let input = format!("{:a<valid$}{:b<invalid$}", "", "", valid=valid, invalid=invalid); let expected = model_complete_take_while_m_n(m, n, valid, &input); if m <= n { - let actual = take_while_m_n(m, n, |c: char| c == 'a').parse_next(input.as_str()); + let actual = take_while(m..=n, |c: char| c == 'a').parse_next(input.as_str()); assert_eq!(expected, actual); } } @@ -161,7 +160,7 @@ fn partial_none_of_test() { #[test] fn partial_is_a() { fn a_or_b(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - take_while1("ab").parse_next(i) + take_while(1.., "ab").parse_next(i) } let a = Partial::new(&b"abcd"[..]); @@ -237,7 +236,7 @@ fn partial_take_until_incomplete_s() { #[test] fn partial_recognize() { - use crate::character::{ + use crate::ascii::{ alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit, multispace1 as multispace, oct_digit1 as oct_digit, space1 as space, }; @@ -298,7 +297,7 @@ fn partial_recognize() { #[test] fn partial_take_while0() { fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - take_while0(AsChar::is_alpha).parse_next(i) + take_while(0.., AsChar::is_alpha).parse_next(i) } let a = &b""[..]; let b = &b"abcd"[..]; @@ -314,7 +313,7 @@ fn partial_take_while0() { #[test] fn partial_take_while1() { fn f(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - take_while1(AsChar::is_alpha).parse_next(i) + take_while(1.., AsChar::is_alpha).parse_next(i) } let a = &b""[..]; let b = &b"abcd"[..]; @@ -336,7 +335,7 @@ fn partial_take_while1() { #[test] fn partial_take_while_m_n() { fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - take_while_m_n(2, 4, AsChar::is_alpha).parse_next(i) + take_while(2..=4, AsChar::is_alpha).parse_next(i) } let a = &b""[..]; let b = &b"a"[..]; @@ -412,7 +411,7 @@ fn partial_take_till1() { #[test] fn partial_take_while_utf8() { fn f(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while0(|c| c != '點').parse_next(i) + take_while(0.., |c| c != '點').parse_next(i) } assert_eq!( @@ -430,7 +429,7 @@ fn partial_take_while_utf8() { ); fn g(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while0(|c| c == '點').parse_next(i) + take_while(0.., |c| c == '點').parse_next(i) } assert_eq!( @@ -502,7 +501,7 @@ fn partial_take_utf8() { assert_eq!(f(Partial::new("a點b")), Ok((Partial::new(""), "a點b"))); fn g(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while0(|c| c == '點').parse_next(i) + take_while(0.., |c| c == '點').parse_next(i) } assert_eq!( @@ -519,7 +518,7 @@ fn partial_take_utf8() { #[test] fn partial_take_while_m_n_utf8_fixed() { fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while_m_n(1, 1, |c| c == 'A' || c == '😃').parse_next(i) + take_while(1, |c| c == 'A' || c == '😃').parse_next(i) } assert_eq!(parser(Partial::new("A!")), Ok((Partial::new("!"), "A"))); assert_eq!(parser(Partial::new("😃!")), Ok((Partial::new("!"), "😃"))); @@ -528,7 +527,7 @@ fn partial_take_while_m_n_utf8_fixed() { #[test] fn partial_take_while_m_n_utf8_range() { fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while_m_n(1, 2, |c| c == 'A' || c == '😃').parse_next(i) + take_while(1..=2, |c| c == 'A' || c == '😃').parse_next(i) } assert_eq!(parser(Partial::new("A!")), Ok((Partial::new("!"), "A"))); assert_eq!(parser(Partial::new("😃!")), Ok((Partial::new("!"), "😃"))); @@ -537,7 +536,7 @@ fn partial_take_while_m_n_utf8_range() { #[test] fn partial_take_while_m_n_utf8_full_match_fixed() { fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while_m_n(1, 1, |c: char| c.is_alphabetic()).parse_next(i) + take_while(1, |c: char| c.is_alphabetic()).parse_next(i) } assert_eq!(parser(Partial::new("øn")), Ok((Partial::new("n"), "ø"))); } @@ -545,7 +544,7 @@ fn partial_take_while_m_n_utf8_full_match_fixed() { #[test] fn partial_take_while_m_n_utf8_full_match_range() { fn parser(i: Partial<&str>) -> IResult<Partial<&str>, &str> { - take_while_m_n(1, 2, |c: char| c.is_alphabetic()).parse_next(i) + take_while(1..=2, |c: char| c.is_alphabetic()).parse_next(i) } assert_eq!(parser(Partial::new("øn")), Ok((Partial::new(""), "øn"))); } @@ -554,7 +553,7 @@ fn partial_take_while_m_n_utf8_full_match_range() { #[cfg(feature = "std")] fn partial_recognize_take_while0() { fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { - take_while0(AsChar::is_alphanum).parse_next(i) + take_while(0.., AsChar::is_alphanum).parse_next(i) } fn y(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { x.recognize().parse_next(i) @@ -571,7 +570,7 @@ fn partial_recognize_take_while0() { #[test] fn partial_length_bytes() { - use crate::number::le_u8; + use crate::binary::le_u8; fn x(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, &[u8]> { length_data(le_u8).parse_next(i) diff --git a/vendor/winnow/src/trace/internals.rs b/vendor/winnow/src/trace/internals.rs index 2e91f69a8..3a10204b7 100644 --- a/vendor/winnow/src/trace/internals.rs +++ b/vendor/winnow/src/trace/internals.rs @@ -74,30 +74,9 @@ pub fn start<I: Stream>( count: usize, input: &I, ) { - let ansi_color = ansi_color(); - let reset = if ansi_color { - anstyle::Reset.render().to_string() - } else { - "".to_owned() - }; - let gutter_style = if ansi_color { - anstyle::Style::new().bold() - } else { - anstyle::Style::new() - } - .render(); - let input_style = if ansi_color { - anstyle::Style::new().underline() - } else { - anstyle::Style::new() - } - .render(); - let eof_style = if ansi_color { - anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Cyan.into())) - } else { - anstyle::Style::new() - } - .render(); + let gutter_style = anstyle::Style::new().bold(); + let input_style = anstyle::Style::new().underline(); + let eof_style = anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Cyan.into())); let (call_width, input_width) = column_widths(); @@ -132,9 +111,18 @@ pub fn start<I: Stream>( (debug_slice, eof) }; - let writer = std::io::stderr(); + let writer = anstyle_stream::stderr(); let mut writer = writer.lock(); - let _ = writeln!(writer, "{call_column:call_width$} {gutter_style}|{reset} {input_style}{debug_slice}{eof_style}{eof}{reset}"); + let _ = writeln!( + writer, + "{call_column:call_width$} {gutter_style}|{gutter_reset} {input_style}{debug_slice}{input_reset}{eof_style}{eof}{eof_reset}", + gutter_style=gutter_style.render(), + gutter_reset=gutter_style.render_reset(), + input_style=input_style.render(), + input_reset=input_style.render_reset(), + eof_style=eof_style.render(), + eof_reset=eof_style.render_reset(), + ); } pub fn end( @@ -144,18 +132,7 @@ pub fn end( consumed: Option<usize>, severity: Severity, ) { - let ansi_color = ansi_color(); - let reset = if ansi_color { - anstyle::Reset.render().to_string() - } else { - "".to_owned() - }; - let gutter_style = if ansi_color { - anstyle::Style::new().bold() - } else { - anstyle::Style::new() - } - .render(); + let gutter_style = anstyle::Style::new().bold(); let (call_width, _) = column_widths(); @@ -166,105 +143,76 @@ pub fn end( }; let call_column = format!("{:depth$}< {name}{count}", ""); - let (mut status_style, status) = match severity { + let (status_style, status) = match severity { Severity::Success => { - let style = anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Green.into())) - .render(); + let style = anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Green.into())); let status = format!("+{}", consumed.unwrap_or_default()); (style, status) } Severity::Backtrack => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Yellow.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Yellow.into())), "backtrack".to_owned(), ), Severity::Cut => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Red.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into())), "cut".to_owned(), ), Severity::Incomplete => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Red.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into())), "incomplete".to_owned(), ), }; - if !ansi_color { - status_style = anstyle::Style::new().render(); - } - let writer = std::io::stderr(); + let writer = anstyle_stream::stderr(); let mut writer = writer.lock(); let _ = writeln!( writer, - "{status_style}{call_column:call_width$}{reset} {gutter_style}|{reset} {status_style}{status}{reset}" + "{status_style}{call_column:call_width$}{status_reset} {gutter_style}|{gutter_reset} {status_style}{status}{status_reset}", + gutter_style=gutter_style.render(), + gutter_reset=gutter_style.render_reset(), + status_style=status_style.render(), + status_reset=status_style.render_reset(), ); } pub fn result(depth: usize, name: &dyn crate::lib::std::fmt::Display, severity: Severity) { - let ansi_color = ansi_color(); - let reset = if ansi_color { - anstyle::Reset.render().to_string() - } else { - "".to_owned() - }; - let gutter_style = if ansi_color { - anstyle::Style::new().bold() - } else { - anstyle::Style::new() - } - .render(); + let gutter_style = anstyle::Style::new().bold(); let (call_width, _) = column_widths(); let call_column = format!("{:depth$}| {name}", ""); - let (mut status_style, status) = match severity { + let (status_style, status) = match severity { Severity::Success => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Green.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Green.into())), "", ), Severity::Backtrack => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Yellow.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Yellow.into())), "backtrack", ), Severity::Cut => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Red.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into())), "cut", ), Severity::Incomplete => ( - anstyle::Style::new() - .fg_color(Some(anstyle::AnsiColor::Red.into())) - .render(), + anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into())), "incomplete", ), }; - if !ansi_color { - status_style = anstyle::Style::new().render(); - } - let writer = std::io::stderr(); + let writer = anstyle_stream::stderr(); let mut writer = writer.lock(); let _ = writeln!( writer, - "{status_style}{call_column:call_width$}{reset} {gutter_style}|{reset} {status_style}{status}{reset}" + "{status_style}{call_column:call_width$}{status_reset} {gutter_style}|{gutter_reset} {status_style}{status}{status_reset}", + gutter_style=gutter_style.render(), + gutter_reset=gutter_style.render_reset(), + status_style=status_style.render(), + status_reset=status_style.render_reset(), ); } -fn ansi_color() -> bool { - concolor::get(concolor::Stream::Stderr).ansi_color() -} - fn column_widths() -> (usize, usize) { let term_width = term_width(); diff --git a/vendor/winnow/src/trace/mod.rs b/vendor/winnow/src/trace/mod.rs index 59dafba8e..e5eaf9451 100644 --- a/vendor/winnow/src/trace/mod.rs +++ b/vendor/winnow/src/trace/mod.rs @@ -27,14 +27,14 @@ compile_error!("`debug` requires `std`"); /// /// ```rust /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed, IResult}; -/// # use winnow::bytes::take_while_m_n; +/// # use winnow::token::take_while; /// # use winnow::stream::AsChar; /// # use winnow::prelude::*; /// use winnow::trace::trace; /// /// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> { /// trace("short_alpha", -/// take_while_m_n(3, 6, AsChar::is_alpha) +/// take_while(3..=6, AsChar::is_alpha) /// ).parse_next(s) /// } /// @@ -46,6 +46,7 @@ compile_error!("`debug` requires `std`"); /// ``` #[cfg_attr(not(feature = "debug"), allow(unused_variables))] #[cfg_attr(not(feature = "debug"), allow(unused_mut))] +#[cfg_attr(not(feature = "debug"), inline(always))] pub fn trace<I: Stream, O, E>( name: impl crate::lib::std::fmt::Display, mut parser: impl Parser<I, O, E>, |