diff options
Diffstat (limited to 'src/ascii/mod.rs')
-rw-r--r-- | src/ascii/mod.rs | 90 |
1 files changed, 71 insertions, 19 deletions
diff --git a/src/ascii/mod.rs b/src/ascii/mod.rs index 8b3119f..8e6a480 100644 --- a/src/ascii/mod.rs +++ b/src/ascii/mod.rs @@ -10,17 +10,46 @@ use crate::lib::std::ops::{Add, Shl}; use crate::combinator::alt; use crate::combinator::cut_err; use crate::combinator::opt; +use crate::combinator::trace; use crate::error::ParserError; use crate::error::{ErrMode, ErrorKind, Needed}; use crate::stream::{AsBStr, AsChar, ParseSlice, Stream, StreamIsPartial}; use crate::stream::{Compare, CompareResult}; use crate::token::one_of; -use crate::token::take_till0; +use crate::token::take_till; use crate::token::take_while; -use crate::trace::trace; use crate::PResult; use crate::Parser; +/// Mark a value as case-insensitive for ASCII characters +/// +/// # Example +/// ```rust +/// # use winnow::prelude::*; +/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}}; +/// # use winnow::ascii::Caseless; +/// +/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> { +/// Caseless("hello").parse_next(s) +/// } +/// +/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello"))); +/// assert_eq!(parser.parse_peek("hello, World!"), Ok((", World!", "hello"))); +/// assert_eq!(parser.parse_peek("HeLlo, World!"), Ok((", World!", "HeLlo"))); +/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Tag)))); +/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag)))); +/// ``` +#[derive(Copy, Clone, Debug)] +pub struct Caseless<T>(pub T); + +impl Caseless<&str> { + /// Get the byte-representation of this case-insensitive value + #[inline(always)] + pub fn as_bytes(&self) -> Caseless<&[u8]> { + Caseless(self.0.as_bytes()) + } +} + /// Recognizes the string `"\r\n"`. /// /// *Complete version*: Will return an error if there's not enough input data. @@ -72,9 +101,9 @@ where /// ``` /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed}; -/// # use winnow::ascii::not_line_ending; +/// # use winnow::ascii::till_line_ending; /// fn parser<'s>(input: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> { -/// not_line_ending.parse_next(input) +/// till_line_ending.parse_next(input) /// } /// /// assert_eq!(parser.parse_peek("ab\r\nc"), Ok(("\r\nc", "ab"))); @@ -89,32 +118,45 @@ where /// # use winnow::prelude::*; /// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed}; /// # use winnow::Partial; -/// # use winnow::ascii::not_line_ending; -/// assert_eq!(not_line_ending::<_, InputError<_>>.parse_peek(Partial::new("ab\r\nc")), Ok((Partial::new("\r\nc"), "ab"))); -/// assert_eq!(not_line_ending::<_, InputError<_>>.parse_peek(Partial::new("abc")), Err(ErrMode::Incomplete(Needed::new(1)))); -/// assert_eq!(not_line_ending::<_, InputError<_>>.parse_peek(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); -/// assert_eq!(not_line_ending::<_, InputError<_>>.parse_peek(Partial::new("a\rb\nc")), Err(ErrMode::Backtrack(InputError::new(Partial::new("\rb\nc"), ErrorKind::Tag )))); -/// assert_eq!(not_line_ending::<_, InputError<_>>.parse_peek(Partial::new("a\rbc")), Err(ErrMode::Backtrack(InputError::new(Partial::new("\rbc"), ErrorKind::Tag )))); +/// # use winnow::ascii::till_line_ending; +/// assert_eq!(till_line_ending::<_, InputError<_>>.parse_peek(Partial::new("ab\r\nc")), Ok((Partial::new("\r\nc"), "ab"))); +/// assert_eq!(till_line_ending::<_, InputError<_>>.parse_peek(Partial::new("abc")), Err(ErrMode::Incomplete(Needed::new(1)))); +/// assert_eq!(till_line_ending::<_, InputError<_>>.parse_peek(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1)))); +/// assert_eq!(till_line_ending::<_, InputError<_>>.parse_peek(Partial::new("a\rb\nc")), Err(ErrMode::Backtrack(InputError::new(Partial::new("\rb\nc"), ErrorKind::Tag )))); +/// assert_eq!(till_line_ending::<_, InputError<_>>.parse_peek(Partial::new("a\rbc")), Err(ErrMode::Backtrack(InputError::new(Partial::new("\rbc"), ErrorKind::Tag )))); /// ``` #[inline(always)] -pub fn not_line_ending<I, E: ParserError<I>>(input: &mut I) -> PResult<<I as Stream>::Slice, E> +pub fn till_line_ending<I, E: ParserError<I>>(input: &mut I) -> PResult<<I as Stream>::Slice, E> where I: StreamIsPartial, I: Stream, I: Compare<&'static str>, <I as Stream>::Token: AsChar + Clone, { - trace("not_line_ending", move |input: &mut I| { + trace("till_line_ending", move |input: &mut I| { if <I as StreamIsPartial>::is_partial_supported() { - not_line_ending_::<_, _, true>(input) + till_line_ending_::<_, _, true>(input) } else { - not_line_ending_::<_, _, false>(input) + till_line_ending_::<_, _, false>(input) } }) .parse_next(input) } -fn not_line_ending_<I, E: ParserError<I>, const PARTIAL: bool>( +/// Deprecated, replaced with [`till_line_ending`] +#[deprecated(since = "0.5.35", note = "Replaced with `till_line_ending`")] +#[inline(always)] +pub fn not_line_ending<I, E: ParserError<I>>(input: &mut I) -> PResult<<I as Stream>::Slice, E> +where + I: StreamIsPartial, + I: Stream, + I: Compare<&'static str>, + <I as Stream>::Token: AsChar + Clone, +{ + till_line_ending(input) +} + +fn till_line_ending_<I, E: ParserError<I>, const PARTIAL: bool>( input: &mut I, ) -> PResult<<I as Stream>::Slice, E> where @@ -123,7 +165,7 @@ where I: Compare<&'static str>, <I as Stream>::Token: AsChar + Clone, { - let res = take_till0(('\r', '\n')).parse_next(input)?; + let res = take_till(0.., ('\r', '\n')).parse_next(input)?; if input.compare("\r") == CompareResult::Ok { let comp = input.compare("\r\n"); match comp { @@ -423,7 +465,7 @@ where /// /// ## Parsing an integer /// -/// You can use `digit1` in combination with [`Parser::try_map`][crate::Parser::try_map] to parse an integer: +/// You can use `digit1` in combination with [`Parser::try_map`] to parse an integer: /// /// ``` /// # use winnow::prelude::*; @@ -965,6 +1007,7 @@ impl Uint for u128 { } } +/// Deprecated since v0.5.17 impl Uint for i8 { fn checked_mul(self, by: u8, _: sealed::SealedMarker) -> Option<Self> { self.checked_mul(by as Self) @@ -974,6 +1017,7 @@ impl Uint for i8 { } } +/// Deprecated since v0.5.17 impl Uint for i16 { fn checked_mul(self, by: u8, _: sealed::SealedMarker) -> Option<Self> { self.checked_mul(by as Self) @@ -983,6 +1027,7 @@ impl Uint for i16 { } } +/// Deprecated since v0.5.17 impl Uint for i32 { fn checked_mul(self, by: u8, _: sealed::SealedMarker) -> Option<Self> { self.checked_mul(by as Self) @@ -992,6 +1037,7 @@ impl Uint for i32 { } } +/// Deprecated since v0.5.17 impl Uint for i64 { fn checked_mul(self, by: u8, _: sealed::SealedMarker) -> Option<Self> { self.checked_mul(by as Self) @@ -1001,6 +1047,7 @@ impl Uint for i64 { } } +/// Deprecated since v0.5.17 impl Uint for i128 { fn checked_mul(self, by: u8, _: sealed::SealedMarker) -> Option<Self> { self.checked_mul(by as Self) @@ -1318,6 +1365,7 @@ where } #[allow(clippy::trait_duplication_in_bounds)] // HACK: clippy 1.64.0 bug +#[allow(deprecated)] fn recognize_float_or_exceptions<I, E: ParserError<I>>( input: &mut I, ) -> PResult<<I as Stream>::Slice, E> @@ -1332,8 +1380,12 @@ where alt(( recognize_float, crate::token::tag_no_case("nan"), - crate::token::tag_no_case("infinity"), - crate::token::tag_no_case("inf"), + ( + opt(one_of(['+', '-'])), + crate::token::tag_no_case("infinity"), + ) + .recognize(), + (opt(one_of(['+', '-'])), crate::token::tag_no_case("inf")).recognize(), )) .parse_next(input) } |