16855e09eSopenharmony_ci//! Character specific parsers and combinators, streaming version
26855e09eSopenharmony_ci//!
36855e09eSopenharmony_ci//! Functions recognizing specific characters
46855e09eSopenharmony_ci
56855e09eSopenharmony_ciuse crate::branch::alt;
66855e09eSopenharmony_ciuse crate::combinator::opt;
76855e09eSopenharmony_ciuse crate::error::ErrorKind;
86855e09eSopenharmony_ciuse crate::error::ParseError;
96855e09eSopenharmony_ciuse crate::internal::{Err, IResult, Needed};
106855e09eSopenharmony_ciuse crate::lib::std::ops::{Range, RangeFrom, RangeTo};
116855e09eSopenharmony_ciuse crate::traits::{
126855e09eSopenharmony_ci  AsChar, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice,
136855e09eSopenharmony_ci};
146855e09eSopenharmony_ciuse crate::traits::{Compare, CompareResult};
156855e09eSopenharmony_ci
166855e09eSopenharmony_ci/// Recognizes one character.
176855e09eSopenharmony_ci///
186855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
196855e09eSopenharmony_ci/// # Example
206855e09eSopenharmony_ci///
216855e09eSopenharmony_ci/// ```
226855e09eSopenharmony_ci/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
236855e09eSopenharmony_ci/// # use nom::character::streaming::char;
246855e09eSopenharmony_ci/// fn parser(i: &str) -> IResult<&str, char> {
256855e09eSopenharmony_ci///     char('a')(i)
266855e09eSopenharmony_ci/// }
276855e09eSopenharmony_ci/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
286855e09eSopenharmony_ci/// assert_eq!(parser("bc"), Err(Err::Error(Error::new("bc", ErrorKind::Char))));
296855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(1))));
306855e09eSopenharmony_ci/// ```
316855e09eSopenharmony_cipub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
326855e09eSopenharmony_ciwhere
336855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter + InputLength,
346855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar,
356855e09eSopenharmony_ci{
366855e09eSopenharmony_ci  move |i: I| match (i).iter_elements().next().map(|t| {
376855e09eSopenharmony_ci    let b = t.as_char() == c;
386855e09eSopenharmony_ci    (&c, b)
396855e09eSopenharmony_ci  }) {
406855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::new(c.len() - i.input_len()))),
416855e09eSopenharmony_ci    Some((_, false)) => Err(Err::Error(Error::from_char(i, c))),
426855e09eSopenharmony_ci    Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
436855e09eSopenharmony_ci  }
446855e09eSopenharmony_ci}
456855e09eSopenharmony_ci
466855e09eSopenharmony_ci/// Recognizes one character and checks that it satisfies a predicate
476855e09eSopenharmony_ci///
486855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
496855e09eSopenharmony_ci/// # Example
506855e09eSopenharmony_ci///
516855e09eSopenharmony_ci/// ```
526855e09eSopenharmony_ci/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
536855e09eSopenharmony_ci/// # use nom::character::streaming::satisfy;
546855e09eSopenharmony_ci/// fn parser(i: &str) -> IResult<&str, char> {
556855e09eSopenharmony_ci///     satisfy(|c| c == 'a' || c == 'b')(i)
566855e09eSopenharmony_ci/// }
576855e09eSopenharmony_ci/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
586855e09eSopenharmony_ci/// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy))));
596855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::Unknown)));
606855e09eSopenharmony_ci/// ```
616855e09eSopenharmony_cipub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
626855e09eSopenharmony_ciwhere
636855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter,
646855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar,
656855e09eSopenharmony_ci  F: Fn(char) -> bool,
666855e09eSopenharmony_ci{
676855e09eSopenharmony_ci  move |i: I| match (i).iter_elements().next().map(|t| {
686855e09eSopenharmony_ci    let c = t.as_char();
696855e09eSopenharmony_ci    let b = cond(c);
706855e09eSopenharmony_ci    (c, b)
716855e09eSopenharmony_ci  }) {
726855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::Unknown)),
736855e09eSopenharmony_ci    Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
746855e09eSopenharmony_ci    Some((c, true)) => Ok((i.slice(c.len()..), c)),
756855e09eSopenharmony_ci  }
766855e09eSopenharmony_ci}
776855e09eSopenharmony_ci
786855e09eSopenharmony_ci/// Recognizes one of the provided characters.
796855e09eSopenharmony_ci///
806855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
816855e09eSopenharmony_ci/// # Example
826855e09eSopenharmony_ci///
836855e09eSopenharmony_ci/// ```
846855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
856855e09eSopenharmony_ci/// # use nom::character::streaming::one_of;
866855e09eSopenharmony_ci/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("abc")("b"), Ok(("", 'b')));
876855e09eSopenharmony_ci/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")("bc"), Err(Err::Error(("bc", ErrorKind::OneOf))));
886855e09eSopenharmony_ci/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::new(1))));
896855e09eSopenharmony_ci/// ```
906855e09eSopenharmony_cipub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
916855e09eSopenharmony_ciwhere
926855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter,
936855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar + Copy,
946855e09eSopenharmony_ci  T: FindToken<<I as InputIter>::Item>,
956855e09eSopenharmony_ci{
966855e09eSopenharmony_ci  move |i: I| match (i).iter_elements().next().map(|c| (c, list.find_token(c))) {
976855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::new(1))),
986855e09eSopenharmony_ci    Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::OneOf))),
996855e09eSopenharmony_ci    Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
1006855e09eSopenharmony_ci  }
1016855e09eSopenharmony_ci}
1026855e09eSopenharmony_ci
1036855e09eSopenharmony_ci/// Recognizes a character that is not in the provided characters.
1046855e09eSopenharmony_ci///
1056855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
1066855e09eSopenharmony_ci/// # Example
1076855e09eSopenharmony_ci///
1086855e09eSopenharmony_ci/// ```
1096855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
1106855e09eSopenharmony_ci/// # use nom::character::streaming::none_of;
1116855e09eSopenharmony_ci/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("abc")("z"), Ok(("", 'z')));
1126855e09eSopenharmony_ci/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("ab")("a"), Err(Err::Error(("a", ErrorKind::NoneOf))));
1136855e09eSopenharmony_ci/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::new(1))));
1146855e09eSopenharmony_ci/// ```
1156855e09eSopenharmony_cipub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
1166855e09eSopenharmony_ciwhere
1176855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter,
1186855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar + Copy,
1196855e09eSopenharmony_ci  T: FindToken<<I as InputIter>::Item>,
1206855e09eSopenharmony_ci{
1216855e09eSopenharmony_ci  move |i: I| match (i).iter_elements().next().map(|c| (c, !list.find_token(c))) {
1226855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::new(1))),
1236855e09eSopenharmony_ci    Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::NoneOf))),
1246855e09eSopenharmony_ci    Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
1256855e09eSopenharmony_ci  }
1266855e09eSopenharmony_ci}
1276855e09eSopenharmony_ci
1286855e09eSopenharmony_ci/// Recognizes the string "\r\n".
1296855e09eSopenharmony_ci///
1306855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
1316855e09eSopenharmony_ci/// # Example
1326855e09eSopenharmony_ci///
1336855e09eSopenharmony_ci/// ```
1346855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
1356855e09eSopenharmony_ci/// # use nom::character::streaming::crlf;
1366855e09eSopenharmony_ci/// assert_eq!(crlf::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
1376855e09eSopenharmony_ci/// assert_eq!(crlf::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
1386855e09eSopenharmony_ci/// assert_eq!(crlf::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(2))));
1396855e09eSopenharmony_ci/// ```
1406855e09eSopenharmony_cipub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
1416855e09eSopenharmony_ciwhere
1426855e09eSopenharmony_ci  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
1436855e09eSopenharmony_ci  T: InputIter,
1446855e09eSopenharmony_ci  T: Compare<&'static str>,
1456855e09eSopenharmony_ci{
1466855e09eSopenharmony_ci  match input.compare("\r\n") {
1476855e09eSopenharmony_ci    //FIXME: is this the right index?
1486855e09eSopenharmony_ci    CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))),
1496855e09eSopenharmony_ci    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
1506855e09eSopenharmony_ci    CompareResult::Error => {
1516855e09eSopenharmony_ci      let e: ErrorKind = ErrorKind::CrLf;
1526855e09eSopenharmony_ci      Err(Err::Error(E::from_error_kind(input, e)))
1536855e09eSopenharmony_ci    }
1546855e09eSopenharmony_ci  }
1556855e09eSopenharmony_ci}
1566855e09eSopenharmony_ci
1576855e09eSopenharmony_ci/// Recognizes a string of any char except '\r\n' or '\n'.
1586855e09eSopenharmony_ci///
1596855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
1606855e09eSopenharmony_ci/// # Example
1616855e09eSopenharmony_ci///
1626855e09eSopenharmony_ci/// ```
1636855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed};
1646855e09eSopenharmony_ci/// # use nom::character::streaming::not_line_ending;
1656855e09eSopenharmony_ci/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Ok(("\r\nc", "ab")));
1666855e09eSopenharmony_ci/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("abc"), Err(Err::Incomplete(Needed::Unknown)));
1676855e09eSopenharmony_ci/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::Unknown)));
1686855e09eSopenharmony_ci/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rb\nc"), Err(Err::Error(("a\rb\nc", ErrorKind::Tag ))));
1696855e09eSopenharmony_ci/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rbc"), Err(Err::Error(("a\rbc", ErrorKind::Tag ))));
1706855e09eSopenharmony_ci/// ```
1716855e09eSopenharmony_cipub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
1726855e09eSopenharmony_ciwhere
1736855e09eSopenharmony_ci  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
1746855e09eSopenharmony_ci  T: InputIter + InputLength,
1756855e09eSopenharmony_ci  T: Compare<&'static str>,
1766855e09eSopenharmony_ci  <T as InputIter>::Item: AsChar,
1776855e09eSopenharmony_ci  <T as InputIter>::Item: AsChar,
1786855e09eSopenharmony_ci{
1796855e09eSopenharmony_ci  match input.position(|item| {
1806855e09eSopenharmony_ci    let c = item.as_char();
1816855e09eSopenharmony_ci    c == '\r' || c == '\n'
1826855e09eSopenharmony_ci  }) {
1836855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::Unknown)),
1846855e09eSopenharmony_ci    Some(index) => {
1856855e09eSopenharmony_ci      let mut it = input.slice(index..).iter_elements();
1866855e09eSopenharmony_ci      let nth = it.next().unwrap().as_char();
1876855e09eSopenharmony_ci      if nth == '\r' {
1886855e09eSopenharmony_ci        let sliced = input.slice(index..);
1896855e09eSopenharmony_ci        let comp = sliced.compare("\r\n");
1906855e09eSopenharmony_ci        match comp {
1916855e09eSopenharmony_ci          //FIXME: calculate the right index
1926855e09eSopenharmony_ci          CompareResult::Incomplete => Err(Err::Incomplete(Needed::Unknown)),
1936855e09eSopenharmony_ci          CompareResult::Error => {
1946855e09eSopenharmony_ci            let e: ErrorKind = ErrorKind::Tag;
1956855e09eSopenharmony_ci            Err(Err::Error(E::from_error_kind(input, e)))
1966855e09eSopenharmony_ci          }
1976855e09eSopenharmony_ci          CompareResult::Ok => Ok((input.slice(index..), input.slice(..index))),
1986855e09eSopenharmony_ci        }
1996855e09eSopenharmony_ci      } else {
2006855e09eSopenharmony_ci        Ok((input.slice(index..), input.slice(..index)))
2016855e09eSopenharmony_ci      }
2026855e09eSopenharmony_ci    }
2036855e09eSopenharmony_ci  }
2046855e09eSopenharmony_ci}
2056855e09eSopenharmony_ci
2066855e09eSopenharmony_ci/// Recognizes an end of line (both '\n' and '\r\n').
2076855e09eSopenharmony_ci///
2086855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
2096855e09eSopenharmony_ci/// # Example
2106855e09eSopenharmony_ci///
2116855e09eSopenharmony_ci/// ```
2126855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
2136855e09eSopenharmony_ci/// # use nom::character::streaming::line_ending;
2146855e09eSopenharmony_ci/// assert_eq!(line_ending::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
2156855e09eSopenharmony_ci/// assert_eq!(line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
2166855e09eSopenharmony_ci/// assert_eq!(line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
2176855e09eSopenharmony_ci/// ```
2186855e09eSopenharmony_cipub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
2196855e09eSopenharmony_ciwhere
2206855e09eSopenharmony_ci  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
2216855e09eSopenharmony_ci  T: InputIter + InputLength,
2226855e09eSopenharmony_ci  T: Compare<&'static str>,
2236855e09eSopenharmony_ci{
2246855e09eSopenharmony_ci  match input.compare("\n") {
2256855e09eSopenharmony_ci    CompareResult::Ok => Ok((input.slice(1..), input.slice(0..1))),
2266855e09eSopenharmony_ci    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(1))),
2276855e09eSopenharmony_ci    CompareResult::Error => {
2286855e09eSopenharmony_ci      match input.compare("\r\n") {
2296855e09eSopenharmony_ci        //FIXME: is this the right index?
2306855e09eSopenharmony_ci        CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))),
2316855e09eSopenharmony_ci        CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
2326855e09eSopenharmony_ci        CompareResult::Error => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
2336855e09eSopenharmony_ci      }
2346855e09eSopenharmony_ci    }
2356855e09eSopenharmony_ci  }
2366855e09eSopenharmony_ci}
2376855e09eSopenharmony_ci
2386855e09eSopenharmony_ci/// Matches a newline character '\\n'.
2396855e09eSopenharmony_ci///
2406855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
2416855e09eSopenharmony_ci/// # Example
2426855e09eSopenharmony_ci///
2436855e09eSopenharmony_ci/// ```
2446855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
2456855e09eSopenharmony_ci/// # use nom::character::streaming::newline;
2466855e09eSopenharmony_ci/// assert_eq!(newline::<_, (_, ErrorKind)>("\nc"), Ok(("c", '\n')));
2476855e09eSopenharmony_ci/// assert_eq!(newline::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
2486855e09eSopenharmony_ci/// assert_eq!(newline::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
2496855e09eSopenharmony_ci/// ```
2506855e09eSopenharmony_cipub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
2516855e09eSopenharmony_ciwhere
2526855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter + InputLength,
2536855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar,
2546855e09eSopenharmony_ci{
2556855e09eSopenharmony_ci  char('\n')(input)
2566855e09eSopenharmony_ci}
2576855e09eSopenharmony_ci
2586855e09eSopenharmony_ci/// Matches a tab character '\t'.
2596855e09eSopenharmony_ci///
2606855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
2616855e09eSopenharmony_ci/// # Example
2626855e09eSopenharmony_ci///
2636855e09eSopenharmony_ci/// ```
2646855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
2656855e09eSopenharmony_ci/// # use nom::character::streaming::tab;
2666855e09eSopenharmony_ci/// assert_eq!(tab::<_, (_, ErrorKind)>("\tc"), Ok(("c", '\t')));
2676855e09eSopenharmony_ci/// assert_eq!(tab::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
2686855e09eSopenharmony_ci/// assert_eq!(tab::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
2696855e09eSopenharmony_ci/// ```
2706855e09eSopenharmony_cipub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
2716855e09eSopenharmony_ciwhere
2726855e09eSopenharmony_ci  I: Slice<RangeFrom<usize>> + InputIter + InputLength,
2736855e09eSopenharmony_ci  <I as InputIter>::Item: AsChar,
2746855e09eSopenharmony_ci{
2756855e09eSopenharmony_ci  char('\t')(input)
2766855e09eSopenharmony_ci}
2776855e09eSopenharmony_ci
2786855e09eSopenharmony_ci/// Matches one byte as a character. Note that the input type will
2796855e09eSopenharmony_ci/// accept a `str`, but not a `&[u8]`, unlike many other nom parsers.
2806855e09eSopenharmony_ci///
2816855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
2826855e09eSopenharmony_ci/// # Example
2836855e09eSopenharmony_ci///
2846855e09eSopenharmony_ci/// ```
2856855e09eSopenharmony_ci/// # use nom::{character::streaming::anychar, Err, error::ErrorKind, IResult, Needed};
2866855e09eSopenharmony_ci/// assert_eq!(anychar::<_, (_, ErrorKind)>("abc"), Ok(("bc",'a')));
2876855e09eSopenharmony_ci/// assert_eq!(anychar::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
2886855e09eSopenharmony_ci/// ```
2896855e09eSopenharmony_cipub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
2906855e09eSopenharmony_ciwhere
2916855e09eSopenharmony_ci  T: InputIter + InputLength + Slice<RangeFrom<usize>>,
2926855e09eSopenharmony_ci  <T as InputIter>::Item: AsChar,
2936855e09eSopenharmony_ci{
2946855e09eSopenharmony_ci  let mut it = input.iter_indices();
2956855e09eSopenharmony_ci  match it.next() {
2966855e09eSopenharmony_ci    None => Err(Err::Incomplete(Needed::new(1))),
2976855e09eSopenharmony_ci    Some((_, c)) => match it.next() {
2986855e09eSopenharmony_ci      None => Ok((input.slice(input.input_len()..), c.as_char())),
2996855e09eSopenharmony_ci      Some((idx, _)) => Ok((input.slice(idx..), c.as_char())),
3006855e09eSopenharmony_ci    },
3016855e09eSopenharmony_ci  }
3026855e09eSopenharmony_ci}
3036855e09eSopenharmony_ci
3046855e09eSopenharmony_ci/// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
3056855e09eSopenharmony_ci///
3066855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
3076855e09eSopenharmony_ci/// or if no terminating token is found (a non alphabetic character).
3086855e09eSopenharmony_ci/// # Example
3096855e09eSopenharmony_ci///
3106855e09eSopenharmony_ci/// ```
3116855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
3126855e09eSopenharmony_ci/// # use nom::character::streaming::alpha0;
3136855e09eSopenharmony_ci/// assert_eq!(alpha0::<_, (_, ErrorKind)>("ab1c"), Ok(("1c", "ab")));
3146855e09eSopenharmony_ci/// assert_eq!(alpha0::<_, (_, ErrorKind)>("1c"), Ok(("1c", "")));
3156855e09eSopenharmony_ci/// assert_eq!(alpha0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
3166855e09eSopenharmony_ci/// ```
3176855e09eSopenharmony_cipub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
3186855e09eSopenharmony_ciwhere
3196855e09eSopenharmony_ci  T: InputTakeAtPosition,
3206855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
3216855e09eSopenharmony_ci{
3226855e09eSopenharmony_ci  input.split_at_position(|item| !item.is_alpha())
3236855e09eSopenharmony_ci}
3246855e09eSopenharmony_ci
3256855e09eSopenharmony_ci/// Recognizes one or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
3266855e09eSopenharmony_ci///
3276855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
3286855e09eSopenharmony_ci/// or if no terminating token is found (a non alphabetic character).
3296855e09eSopenharmony_ci/// # Example
3306855e09eSopenharmony_ci///
3316855e09eSopenharmony_ci/// ```
3326855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
3336855e09eSopenharmony_ci/// # use nom::character::streaming::alpha1;
3346855e09eSopenharmony_ci/// assert_eq!(alpha1::<_, (_, ErrorKind)>("aB1c"), Ok(("1c", "aB")));
3356855e09eSopenharmony_ci/// assert_eq!(alpha1::<_, (_, ErrorKind)>("1c"), Err(Err::Error(("1c", ErrorKind::Alpha))));
3366855e09eSopenharmony_ci/// assert_eq!(alpha1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
3376855e09eSopenharmony_ci/// ```
3386855e09eSopenharmony_cipub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
3396855e09eSopenharmony_ciwhere
3406855e09eSopenharmony_ci  T: InputTakeAtPosition,
3416855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
3426855e09eSopenharmony_ci{
3436855e09eSopenharmony_ci  input.split_at_position1(|item| !item.is_alpha(), ErrorKind::Alpha)
3446855e09eSopenharmony_ci}
3456855e09eSopenharmony_ci
3466855e09eSopenharmony_ci/// Recognizes zero or more ASCII numerical characters: 0-9
3476855e09eSopenharmony_ci///
3486855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
3496855e09eSopenharmony_ci/// or if no terminating token is found (a non digit character).
3506855e09eSopenharmony_ci/// # Example
3516855e09eSopenharmony_ci///
3526855e09eSopenharmony_ci/// ```
3536855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
3546855e09eSopenharmony_ci/// # use nom::character::streaming::digit0;
3556855e09eSopenharmony_ci/// assert_eq!(digit0::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
3566855e09eSopenharmony_ci/// assert_eq!(digit0::<_, (_, ErrorKind)>("a21c"), Ok(("a21c", "")));
3576855e09eSopenharmony_ci/// assert_eq!(digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
3586855e09eSopenharmony_ci/// ```
3596855e09eSopenharmony_cipub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
3606855e09eSopenharmony_ciwhere
3616855e09eSopenharmony_ci  T: InputTakeAtPosition,
3626855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
3636855e09eSopenharmony_ci{
3646855e09eSopenharmony_ci  input.split_at_position(|item| !item.is_dec_digit())
3656855e09eSopenharmony_ci}
3666855e09eSopenharmony_ci
3676855e09eSopenharmony_ci/// Recognizes one or more ASCII numerical characters: 0-9
3686855e09eSopenharmony_ci///
3696855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
3706855e09eSopenharmony_ci/// or if no terminating token is found (a non digit character).
3716855e09eSopenharmony_ci/// # Example
3726855e09eSopenharmony_ci///
3736855e09eSopenharmony_ci/// ```
3746855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
3756855e09eSopenharmony_ci/// # use nom::character::streaming::digit1;
3766855e09eSopenharmony_ci/// assert_eq!(digit1::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
3776855e09eSopenharmony_ci/// assert_eq!(digit1::<_, (_, ErrorKind)>("c1"), Err(Err::Error(("c1", ErrorKind::Digit))));
3786855e09eSopenharmony_ci/// assert_eq!(digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
3796855e09eSopenharmony_ci/// ```
3806855e09eSopenharmony_cipub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
3816855e09eSopenharmony_ciwhere
3826855e09eSopenharmony_ci  T: InputTakeAtPosition,
3836855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
3846855e09eSopenharmony_ci{
3856855e09eSopenharmony_ci  input.split_at_position1(|item| !item.is_dec_digit(), ErrorKind::Digit)
3866855e09eSopenharmony_ci}
3876855e09eSopenharmony_ci
3886855e09eSopenharmony_ci/// Recognizes zero or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
3896855e09eSopenharmony_ci///
3906855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
3916855e09eSopenharmony_ci/// or if no terminating token is found (a non hexadecimal digit character).
3926855e09eSopenharmony_ci/// # Example
3936855e09eSopenharmony_ci///
3946855e09eSopenharmony_ci/// ```
3956855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
3966855e09eSopenharmony_ci/// # use nom::character::streaming::hex_digit0;
3976855e09eSopenharmony_ci/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
3986855e09eSopenharmony_ci/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
3996855e09eSopenharmony_ci/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
4006855e09eSopenharmony_ci/// ```
4016855e09eSopenharmony_cipub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
4026855e09eSopenharmony_ciwhere
4036855e09eSopenharmony_ci  T: InputTakeAtPosition,
4046855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
4056855e09eSopenharmony_ci{
4066855e09eSopenharmony_ci  input.split_at_position(|item| !item.is_hex_digit())
4076855e09eSopenharmony_ci}
4086855e09eSopenharmony_ci
4096855e09eSopenharmony_ci/// Recognizes one or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
4106855e09eSopenharmony_ci///
4116855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
4126855e09eSopenharmony_ci/// or if no terminating token is found (a non hexadecimal digit character).
4136855e09eSopenharmony_ci/// # Example
4146855e09eSopenharmony_ci///
4156855e09eSopenharmony_ci/// ```
4166855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
4176855e09eSopenharmony_ci/// # use nom::character::streaming::hex_digit1;
4186855e09eSopenharmony_ci/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
4196855e09eSopenharmony_ci/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::HexDigit))));
4206855e09eSopenharmony_ci/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
4216855e09eSopenharmony_ci/// ```
4226855e09eSopenharmony_cipub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
4236855e09eSopenharmony_ciwhere
4246855e09eSopenharmony_ci  T: InputTakeAtPosition,
4256855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
4266855e09eSopenharmony_ci{
4276855e09eSopenharmony_ci  input.split_at_position1(|item| !item.is_hex_digit(), ErrorKind::HexDigit)
4286855e09eSopenharmony_ci}
4296855e09eSopenharmony_ci
4306855e09eSopenharmony_ci/// Recognizes zero or more octal characters: 0-7
4316855e09eSopenharmony_ci///
4326855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
4336855e09eSopenharmony_ci/// or if no terminating token is found (a non octal digit character).
4346855e09eSopenharmony_ci/// # Example
4356855e09eSopenharmony_ci///
4366855e09eSopenharmony_ci/// ```
4376855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
4386855e09eSopenharmony_ci/// # use nom::character::streaming::oct_digit0;
4396855e09eSopenharmony_ci/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
4406855e09eSopenharmony_ci/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
4416855e09eSopenharmony_ci/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
4426855e09eSopenharmony_ci/// ```
4436855e09eSopenharmony_cipub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
4446855e09eSopenharmony_ciwhere
4456855e09eSopenharmony_ci  T: InputTakeAtPosition,
4466855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
4476855e09eSopenharmony_ci{
4486855e09eSopenharmony_ci  input.split_at_position(|item| !item.is_oct_digit())
4496855e09eSopenharmony_ci}
4506855e09eSopenharmony_ci
4516855e09eSopenharmony_ci/// Recognizes one or more octal characters: 0-7
4526855e09eSopenharmony_ci///
4536855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
4546855e09eSopenharmony_ci/// or if no terminating token is found (a non octal digit character).
4556855e09eSopenharmony_ci/// # Example
4566855e09eSopenharmony_ci///
4576855e09eSopenharmony_ci/// ```
4586855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
4596855e09eSopenharmony_ci/// # use nom::character::streaming::oct_digit1;
4606855e09eSopenharmony_ci/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
4616855e09eSopenharmony_ci/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::OctDigit))));
4626855e09eSopenharmony_ci/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
4636855e09eSopenharmony_ci/// ```
4646855e09eSopenharmony_cipub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
4656855e09eSopenharmony_ciwhere
4666855e09eSopenharmony_ci  T: InputTakeAtPosition,
4676855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
4686855e09eSopenharmony_ci{
4696855e09eSopenharmony_ci  input.split_at_position1(|item| !item.is_oct_digit(), ErrorKind::OctDigit)
4706855e09eSopenharmony_ci}
4716855e09eSopenharmony_ci
4726855e09eSopenharmony_ci/// Recognizes zero or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
4736855e09eSopenharmony_ci///
4746855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
4756855e09eSopenharmony_ci/// or if no terminating token is found (a non alphanumerical character).
4766855e09eSopenharmony_ci/// # Example
4776855e09eSopenharmony_ci///
4786855e09eSopenharmony_ci/// ```
4796855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
4806855e09eSopenharmony_ci/// # use nom::character::streaming::alphanumeric0;
4816855e09eSopenharmony_ci/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
4826855e09eSopenharmony_ci/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("&Z21c"), Ok(("&Z21c", "")));
4836855e09eSopenharmony_ci/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
4846855e09eSopenharmony_ci/// ```
4856855e09eSopenharmony_cipub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
4866855e09eSopenharmony_ciwhere
4876855e09eSopenharmony_ci  T: InputTakeAtPosition,
4886855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
4896855e09eSopenharmony_ci{
4906855e09eSopenharmony_ci  input.split_at_position(|item| !item.is_alphanum())
4916855e09eSopenharmony_ci}
4926855e09eSopenharmony_ci
4936855e09eSopenharmony_ci/// Recognizes one or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
4946855e09eSopenharmony_ci///
4956855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
4966855e09eSopenharmony_ci/// or if no terminating token is found (a non alphanumerical character).
4976855e09eSopenharmony_ci/// # Example
4986855e09eSopenharmony_ci///
4996855e09eSopenharmony_ci/// ```
5006855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
5016855e09eSopenharmony_ci/// # use nom::character::streaming::alphanumeric1;
5026855e09eSopenharmony_ci/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
5036855e09eSopenharmony_ci/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("&H2"), Err(Err::Error(("&H2", ErrorKind::AlphaNumeric))));
5046855e09eSopenharmony_ci/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
5056855e09eSopenharmony_ci/// ```
5066855e09eSopenharmony_cipub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
5076855e09eSopenharmony_ciwhere
5086855e09eSopenharmony_ci  T: InputTakeAtPosition,
5096855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar,
5106855e09eSopenharmony_ci{
5116855e09eSopenharmony_ci  input.split_at_position1(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric)
5126855e09eSopenharmony_ci}
5136855e09eSopenharmony_ci
5146855e09eSopenharmony_ci/// Recognizes zero or more spaces and tabs.
5156855e09eSopenharmony_ci///
5166855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
5176855e09eSopenharmony_ci/// or if no terminating token is found (a non space character).
5186855e09eSopenharmony_ci/// # Example
5196855e09eSopenharmony_ci///
5206855e09eSopenharmony_ci/// ```
5216855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
5226855e09eSopenharmony_ci/// # use nom::character::streaming::space0;
5236855e09eSopenharmony_ci/// assert_eq!(space0::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
5246855e09eSopenharmony_ci/// assert_eq!(space0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
5256855e09eSopenharmony_ci/// assert_eq!(space0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
5266855e09eSopenharmony_ci/// ```
5276855e09eSopenharmony_cipub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
5286855e09eSopenharmony_ciwhere
5296855e09eSopenharmony_ci  T: InputTakeAtPosition,
5306855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar + Clone,
5316855e09eSopenharmony_ci{
5326855e09eSopenharmony_ci  input.split_at_position(|item| {
5336855e09eSopenharmony_ci    let c = item.as_char();
5346855e09eSopenharmony_ci    !(c == ' ' || c == '\t')
5356855e09eSopenharmony_ci  })
5366855e09eSopenharmony_ci}
5376855e09eSopenharmony_ci/// Recognizes one or more spaces and tabs.
5386855e09eSopenharmony_ci///
5396855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
5406855e09eSopenharmony_ci/// or if no terminating token is found (a non space character).
5416855e09eSopenharmony_ci/// # Example
5426855e09eSopenharmony_ci///
5436855e09eSopenharmony_ci/// ```
5446855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
5456855e09eSopenharmony_ci/// # use nom::character::streaming::space1;
5466855e09eSopenharmony_ci/// assert_eq!(space1::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
5476855e09eSopenharmony_ci/// assert_eq!(space1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::Space))));
5486855e09eSopenharmony_ci/// assert_eq!(space1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
5496855e09eSopenharmony_ci/// ```
5506855e09eSopenharmony_cipub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
5516855e09eSopenharmony_ciwhere
5526855e09eSopenharmony_ci  T: InputTakeAtPosition,
5536855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar + Clone,
5546855e09eSopenharmony_ci{
5556855e09eSopenharmony_ci  input.split_at_position1(
5566855e09eSopenharmony_ci    |item| {
5576855e09eSopenharmony_ci      let c = item.as_char();
5586855e09eSopenharmony_ci      !(c == ' ' || c == '\t')
5596855e09eSopenharmony_ci    },
5606855e09eSopenharmony_ci    ErrorKind::Space,
5616855e09eSopenharmony_ci  )
5626855e09eSopenharmony_ci}
5636855e09eSopenharmony_ci
5646855e09eSopenharmony_ci/// Recognizes zero or more spaces, tabs, carriage returns and line feeds.
5656855e09eSopenharmony_ci///
5666855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
5676855e09eSopenharmony_ci/// or if no terminating token is found (a non space character).
5686855e09eSopenharmony_ci/// # Example
5696855e09eSopenharmony_ci///
5706855e09eSopenharmony_ci/// ```
5716855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
5726855e09eSopenharmony_ci/// # use nom::character::streaming::multispace0;
5736855e09eSopenharmony_ci/// assert_eq!(multispace0::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
5746855e09eSopenharmony_ci/// assert_eq!(multispace0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
5756855e09eSopenharmony_ci/// assert_eq!(multispace0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
5766855e09eSopenharmony_ci/// ```
5776855e09eSopenharmony_cipub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
5786855e09eSopenharmony_ciwhere
5796855e09eSopenharmony_ci  T: InputTakeAtPosition,
5806855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar + Clone,
5816855e09eSopenharmony_ci{
5826855e09eSopenharmony_ci  input.split_at_position(|item| {
5836855e09eSopenharmony_ci    let c = item.as_char();
5846855e09eSopenharmony_ci    !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
5856855e09eSopenharmony_ci  })
5866855e09eSopenharmony_ci}
5876855e09eSopenharmony_ci
5886855e09eSopenharmony_ci/// Recognizes one or more spaces, tabs, carriage returns and line feeds.
5896855e09eSopenharmony_ci///
5906855e09eSopenharmony_ci/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
5916855e09eSopenharmony_ci/// or if no terminating token is found (a non space character).
5926855e09eSopenharmony_ci/// # Example
5936855e09eSopenharmony_ci///
5946855e09eSopenharmony_ci/// ```
5956855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, IResult, Needed};
5966855e09eSopenharmony_ci/// # use nom::character::streaming::multispace1;
5976855e09eSopenharmony_ci/// assert_eq!(multispace1::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
5986855e09eSopenharmony_ci/// assert_eq!(multispace1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::MultiSpace))));
5996855e09eSopenharmony_ci/// assert_eq!(multispace1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
6006855e09eSopenharmony_ci/// ```
6016855e09eSopenharmony_cipub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
6026855e09eSopenharmony_ciwhere
6036855e09eSopenharmony_ci  T: InputTakeAtPosition,
6046855e09eSopenharmony_ci  <T as InputTakeAtPosition>::Item: AsChar + Clone,
6056855e09eSopenharmony_ci{
6066855e09eSopenharmony_ci  input.split_at_position1(
6076855e09eSopenharmony_ci    |item| {
6086855e09eSopenharmony_ci      let c = item.as_char();
6096855e09eSopenharmony_ci      !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
6106855e09eSopenharmony_ci    },
6116855e09eSopenharmony_ci    ErrorKind::MultiSpace,
6126855e09eSopenharmony_ci  )
6136855e09eSopenharmony_ci}
6146855e09eSopenharmony_ci
6156855e09eSopenharmony_cipub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
6166855e09eSopenharmony_ciwhere
6176855e09eSopenharmony_ci  T: Clone + InputTake + InputLength,
6186855e09eSopenharmony_ci  T: for<'a> Compare<&'a [u8]>,
6196855e09eSopenharmony_ci{
6206855e09eSopenharmony_ci  use crate::bytes::streaming::tag;
6216855e09eSopenharmony_ci  use crate::combinator::value;
6226855e09eSopenharmony_ci
6236855e09eSopenharmony_ci  let (i, opt_sign) = opt(alt((
6246855e09eSopenharmony_ci    value(false, tag(&b"-"[..])),
6256855e09eSopenharmony_ci    value(true, tag(&b"+"[..])),
6266855e09eSopenharmony_ci  )))(input)?;
6276855e09eSopenharmony_ci  let sign = opt_sign.unwrap_or(true);
6286855e09eSopenharmony_ci
6296855e09eSopenharmony_ci  Ok((i, sign))
6306855e09eSopenharmony_ci}
6316855e09eSopenharmony_ci
6326855e09eSopenharmony_ci#[doc(hidden)]
6336855e09eSopenharmony_cimacro_rules! ints {
6346855e09eSopenharmony_ci    ($($t:tt)+) => {
6356855e09eSopenharmony_ci        $(
6366855e09eSopenharmony_ci        /// will parse a number in text form to a number
6376855e09eSopenharmony_ci        ///
6386855e09eSopenharmony_ci        /// *Complete version*: can parse until the end of input.
6396855e09eSopenharmony_ci        pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
6406855e09eSopenharmony_ci            where
6416855e09eSopenharmony_ci            T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone,
6426855e09eSopenharmony_ci            <T as InputIter>::Item: AsChar,
6436855e09eSopenharmony_ci            T: for <'a> Compare<&'a[u8]>,
6446855e09eSopenharmony_ci            {
6456855e09eSopenharmony_ci              let (i, sign) = sign(input.clone())?;
6466855e09eSopenharmony_ci
6476855e09eSopenharmony_ci                if i.input_len() == 0 {
6486855e09eSopenharmony_ci                    return Err(Err::Incomplete(Needed::new(1)));
6496855e09eSopenharmony_ci                }
6506855e09eSopenharmony_ci
6516855e09eSopenharmony_ci                let mut value: $t = 0;
6526855e09eSopenharmony_ci                if sign {
6536855e09eSopenharmony_ci                    for (pos, c) in i.iter_indices() {
6546855e09eSopenharmony_ci                        match c.as_char().to_digit(10) {
6556855e09eSopenharmony_ci                            None => {
6566855e09eSopenharmony_ci                                if pos == 0 {
6576855e09eSopenharmony_ci                                    return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
6586855e09eSopenharmony_ci                                } else {
6596855e09eSopenharmony_ci                                    return Ok((i.slice(pos..), value));
6606855e09eSopenharmony_ci                                }
6616855e09eSopenharmony_ci                            },
6626855e09eSopenharmony_ci                            Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
6636855e09eSopenharmony_ci                                None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
6646855e09eSopenharmony_ci                                Some(v) => value = v,
6656855e09eSopenharmony_ci                            }
6666855e09eSopenharmony_ci                        }
6676855e09eSopenharmony_ci                    }
6686855e09eSopenharmony_ci                } else {
6696855e09eSopenharmony_ci                    for (pos, c) in i.iter_indices() {
6706855e09eSopenharmony_ci                        match c.as_char().to_digit(10) {
6716855e09eSopenharmony_ci                            None => {
6726855e09eSopenharmony_ci                                if pos == 0 {
6736855e09eSopenharmony_ci                                    return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
6746855e09eSopenharmony_ci                                } else {
6756855e09eSopenharmony_ci                                    return Ok((i.slice(pos..), value));
6766855e09eSopenharmony_ci                                }
6776855e09eSopenharmony_ci                            },
6786855e09eSopenharmony_ci                            Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) {
6796855e09eSopenharmony_ci                                None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
6806855e09eSopenharmony_ci                                Some(v) => value = v,
6816855e09eSopenharmony_ci                            }
6826855e09eSopenharmony_ci                        }
6836855e09eSopenharmony_ci                    }
6846855e09eSopenharmony_ci                }
6856855e09eSopenharmony_ci
6866855e09eSopenharmony_ci                Err(Err::Incomplete(Needed::new(1)))
6876855e09eSopenharmony_ci            }
6886855e09eSopenharmony_ci        )+
6896855e09eSopenharmony_ci    }
6906855e09eSopenharmony_ci}
6916855e09eSopenharmony_ci
6926855e09eSopenharmony_ciints! { i8 i16 i32 i64 i128 }
6936855e09eSopenharmony_ci
6946855e09eSopenharmony_ci#[doc(hidden)]
6956855e09eSopenharmony_cimacro_rules! uints {
6966855e09eSopenharmony_ci    ($($t:tt)+) => {
6976855e09eSopenharmony_ci        $(
6986855e09eSopenharmony_ci        /// will parse a number in text form to a number
6996855e09eSopenharmony_ci        ///
7006855e09eSopenharmony_ci        /// *Complete version*: can parse until the end of input.
7016855e09eSopenharmony_ci        pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
7026855e09eSopenharmony_ci            where
7036855e09eSopenharmony_ci            T: InputIter + Slice<RangeFrom<usize>> + InputLength,
7046855e09eSopenharmony_ci            <T as InputIter>::Item: AsChar,
7056855e09eSopenharmony_ci            {
7066855e09eSopenharmony_ci                let i = input;
7076855e09eSopenharmony_ci
7086855e09eSopenharmony_ci                if i.input_len() == 0 {
7096855e09eSopenharmony_ci                    return Err(Err::Incomplete(Needed::new(1)));
7106855e09eSopenharmony_ci                }
7116855e09eSopenharmony_ci
7126855e09eSopenharmony_ci                let mut value: $t = 0;
7136855e09eSopenharmony_ci                for (pos, c) in i.iter_indices() {
7146855e09eSopenharmony_ci                    match c.as_char().to_digit(10) {
7156855e09eSopenharmony_ci                        None => {
7166855e09eSopenharmony_ci                            if pos == 0 {
7176855e09eSopenharmony_ci                                return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
7186855e09eSopenharmony_ci                            } else {
7196855e09eSopenharmony_ci                                return Ok((i.slice(pos..), value));
7206855e09eSopenharmony_ci                            }
7216855e09eSopenharmony_ci                        },
7226855e09eSopenharmony_ci                        Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
7236855e09eSopenharmony_ci                            None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))),
7246855e09eSopenharmony_ci                            Some(v) => value = v,
7256855e09eSopenharmony_ci                        }
7266855e09eSopenharmony_ci                    }
7276855e09eSopenharmony_ci                }
7286855e09eSopenharmony_ci
7296855e09eSopenharmony_ci                Err(Err::Incomplete(Needed::new(1)))
7306855e09eSopenharmony_ci            }
7316855e09eSopenharmony_ci        )+
7326855e09eSopenharmony_ci    }
7336855e09eSopenharmony_ci}
7346855e09eSopenharmony_ci
7356855e09eSopenharmony_ciuints! { u8 u16 u32 u64 u128 }
7366855e09eSopenharmony_ci
7376855e09eSopenharmony_ci#[cfg(test)]
7386855e09eSopenharmony_cimod tests {
7396855e09eSopenharmony_ci  use super::*;
7406855e09eSopenharmony_ci  use crate::error::ErrorKind;
7416855e09eSopenharmony_ci  use crate::internal::{Err, Needed};
7426855e09eSopenharmony_ci  use crate::sequence::pair;
7436855e09eSopenharmony_ci  use crate::traits::ParseTo;
7446855e09eSopenharmony_ci  use proptest::prelude::*;
7456855e09eSopenharmony_ci
7466855e09eSopenharmony_ci  macro_rules! assert_parse(
7476855e09eSopenharmony_ci    ($left: expr, $right: expr) => {
7486855e09eSopenharmony_ci      let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
7496855e09eSopenharmony_ci      assert_eq!(res, $right);
7506855e09eSopenharmony_ci    };
7516855e09eSopenharmony_ci  );
7526855e09eSopenharmony_ci
7536855e09eSopenharmony_ci  #[test]
7546855e09eSopenharmony_ci  fn anychar_str() {
7556855e09eSopenharmony_ci    use super::anychar;
7566855e09eSopenharmony_ci    assert_eq!(anychar::<_, (&str, ErrorKind)>("Ә"), Ok(("", 'Ә')));
7576855e09eSopenharmony_ci  }
7586855e09eSopenharmony_ci
7596855e09eSopenharmony_ci  #[test]
7606855e09eSopenharmony_ci  fn character() {
7616855e09eSopenharmony_ci    let a: &[u8] = b"abcd";
7626855e09eSopenharmony_ci    let b: &[u8] = b"1234";
7636855e09eSopenharmony_ci    let c: &[u8] = b"a123";
7646855e09eSopenharmony_ci    let d: &[u8] = "azé12".as_bytes();
7656855e09eSopenharmony_ci    let e: &[u8] = b" ";
7666855e09eSopenharmony_ci    let f: &[u8] = b" ;";
7676855e09eSopenharmony_ci    //assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
7686855e09eSopenharmony_ci    assert_parse!(alpha1(a), Err(Err::Incomplete(Needed::new(1))));
7696855e09eSopenharmony_ci    assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
7706855e09eSopenharmony_ci    assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
7716855e09eSopenharmony_ci    assert_eq!(
7726855e09eSopenharmony_ci      alpha1::<_, (_, ErrorKind)>(d),
7736855e09eSopenharmony_ci      Ok(("é12".as_bytes(), &b"az"[..]))
7746855e09eSopenharmony_ci    );
7756855e09eSopenharmony_ci    assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
7766855e09eSopenharmony_ci    assert_eq!(
7776855e09eSopenharmony_ci      digit1::<_, (_, ErrorKind)>(b),
7786855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
7796855e09eSopenharmony_ci    );
7806855e09eSopenharmony_ci    assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
7816855e09eSopenharmony_ci    assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
7826855e09eSopenharmony_ci    assert_eq!(
7836855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(a),
7846855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
7856855e09eSopenharmony_ci    );
7866855e09eSopenharmony_ci    assert_eq!(
7876855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(b),
7886855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
7896855e09eSopenharmony_ci    );
7906855e09eSopenharmony_ci    assert_eq!(
7916855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(c),
7926855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
7936855e09eSopenharmony_ci    );
7946855e09eSopenharmony_ci    assert_eq!(
7956855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(d),
7966855e09eSopenharmony_ci      Ok(("zé12".as_bytes(), &b"a"[..]))
7976855e09eSopenharmony_ci    );
7986855e09eSopenharmony_ci    assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
7996855e09eSopenharmony_ci    assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
8006855e09eSopenharmony_ci    assert_eq!(
8016855e09eSopenharmony_ci      oct_digit1::<_, (_, ErrorKind)>(b),
8026855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8036855e09eSopenharmony_ci    );
8046855e09eSopenharmony_ci    assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
8056855e09eSopenharmony_ci    assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
8066855e09eSopenharmony_ci    assert_eq!(
8076855e09eSopenharmony_ci      alphanumeric1::<_, (_, ErrorKind)>(a),
8086855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8096855e09eSopenharmony_ci    );
8106855e09eSopenharmony_ci    //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
8116855e09eSopenharmony_ci    assert_eq!(
8126855e09eSopenharmony_ci      alphanumeric1::<_, (_, ErrorKind)>(c),
8136855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8146855e09eSopenharmony_ci    );
8156855e09eSopenharmony_ci    assert_eq!(
8166855e09eSopenharmony_ci      alphanumeric1::<_, (_, ErrorKind)>(d),
8176855e09eSopenharmony_ci      Ok(("é12".as_bytes(), &b"az"[..]))
8186855e09eSopenharmony_ci    );
8196855e09eSopenharmony_ci    assert_eq!(
8206855e09eSopenharmony_ci      space1::<_, (_, ErrorKind)>(e),
8216855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8226855e09eSopenharmony_ci    );
8236855e09eSopenharmony_ci    assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
8246855e09eSopenharmony_ci  }
8256855e09eSopenharmony_ci
8266855e09eSopenharmony_ci  #[cfg(feature = "alloc")]
8276855e09eSopenharmony_ci  #[test]
8286855e09eSopenharmony_ci  fn character_s() {
8296855e09eSopenharmony_ci    let a = "abcd";
8306855e09eSopenharmony_ci    let b = "1234";
8316855e09eSopenharmony_ci    let c = "a123";
8326855e09eSopenharmony_ci    let d = "azé12";
8336855e09eSopenharmony_ci    let e = " ";
8346855e09eSopenharmony_ci    assert_eq!(
8356855e09eSopenharmony_ci      alpha1::<_, (_, ErrorKind)>(a),
8366855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8376855e09eSopenharmony_ci    );
8386855e09eSopenharmony_ci    assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
8396855e09eSopenharmony_ci    assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..])));
8406855e09eSopenharmony_ci    assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..])));
8416855e09eSopenharmony_ci    assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
8426855e09eSopenharmony_ci    assert_eq!(
8436855e09eSopenharmony_ci      digit1::<_, (_, ErrorKind)>(b),
8446855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8456855e09eSopenharmony_ci    );
8466855e09eSopenharmony_ci    assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
8476855e09eSopenharmony_ci    assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
8486855e09eSopenharmony_ci    assert_eq!(
8496855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(a),
8506855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8516855e09eSopenharmony_ci    );
8526855e09eSopenharmony_ci    assert_eq!(
8536855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(b),
8546855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8556855e09eSopenharmony_ci    );
8566855e09eSopenharmony_ci    assert_eq!(
8576855e09eSopenharmony_ci      hex_digit1::<_, (_, ErrorKind)>(c),
8586855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8596855e09eSopenharmony_ci    );
8606855e09eSopenharmony_ci    assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
8616855e09eSopenharmony_ci    assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
8626855e09eSopenharmony_ci    assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
8636855e09eSopenharmony_ci    assert_eq!(
8646855e09eSopenharmony_ci      oct_digit1::<_, (_, ErrorKind)>(b),
8656855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8666855e09eSopenharmony_ci    );
8676855e09eSopenharmony_ci    assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
8686855e09eSopenharmony_ci    assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
8696855e09eSopenharmony_ci    assert_eq!(
8706855e09eSopenharmony_ci      alphanumeric1::<_, (_, ErrorKind)>(a),
8716855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8726855e09eSopenharmony_ci    );
8736855e09eSopenharmony_ci    //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
8746855e09eSopenharmony_ci    assert_eq!(
8756855e09eSopenharmony_ci      alphanumeric1::<_, (_, ErrorKind)>(c),
8766855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8776855e09eSopenharmony_ci    );
8786855e09eSopenharmony_ci    assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
8796855e09eSopenharmony_ci    assert_eq!(
8806855e09eSopenharmony_ci      space1::<_, (_, ErrorKind)>(e),
8816855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(1)))
8826855e09eSopenharmony_ci    );
8836855e09eSopenharmony_ci  }
8846855e09eSopenharmony_ci
8856855e09eSopenharmony_ci  use crate::traits::Offset;
8866855e09eSopenharmony_ci  #[test]
8876855e09eSopenharmony_ci  fn offset() {
8886855e09eSopenharmony_ci    let a = &b"abcd;"[..];
8896855e09eSopenharmony_ci    let b = &b"1234;"[..];
8906855e09eSopenharmony_ci    let c = &b"a123;"[..];
8916855e09eSopenharmony_ci    let d = &b" \t;"[..];
8926855e09eSopenharmony_ci    let e = &b" \t\r\n;"[..];
8936855e09eSopenharmony_ci    let f = &b"123abcDEF;"[..];
8946855e09eSopenharmony_ci
8956855e09eSopenharmony_ci    match alpha1::<_, (_, ErrorKind)>(a) {
8966855e09eSopenharmony_ci      Ok((i, _)) => {
8976855e09eSopenharmony_ci        assert_eq!(a.offset(i) + i.len(), a.len());
8986855e09eSopenharmony_ci      }
8996855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for alpha"),
9006855e09eSopenharmony_ci    }
9016855e09eSopenharmony_ci    match digit1::<_, (_, ErrorKind)>(b) {
9026855e09eSopenharmony_ci      Ok((i, _)) => {
9036855e09eSopenharmony_ci        assert_eq!(b.offset(i) + i.len(), b.len());
9046855e09eSopenharmony_ci      }
9056855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for digit"),
9066855e09eSopenharmony_ci    }
9076855e09eSopenharmony_ci    match alphanumeric1::<_, (_, ErrorKind)>(c) {
9086855e09eSopenharmony_ci      Ok((i, _)) => {
9096855e09eSopenharmony_ci        assert_eq!(c.offset(i) + i.len(), c.len());
9106855e09eSopenharmony_ci      }
9116855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for alphanumeric"),
9126855e09eSopenharmony_ci    }
9136855e09eSopenharmony_ci    match space1::<_, (_, ErrorKind)>(d) {
9146855e09eSopenharmony_ci      Ok((i, _)) => {
9156855e09eSopenharmony_ci        assert_eq!(d.offset(i) + i.len(), d.len());
9166855e09eSopenharmony_ci      }
9176855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for space"),
9186855e09eSopenharmony_ci    }
9196855e09eSopenharmony_ci    match multispace1::<_, (_, ErrorKind)>(e) {
9206855e09eSopenharmony_ci      Ok((i, _)) => {
9216855e09eSopenharmony_ci        assert_eq!(e.offset(i) + i.len(), e.len());
9226855e09eSopenharmony_ci      }
9236855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for multispace"),
9246855e09eSopenharmony_ci    }
9256855e09eSopenharmony_ci    match hex_digit1::<_, (_, ErrorKind)>(f) {
9266855e09eSopenharmony_ci      Ok((i, _)) => {
9276855e09eSopenharmony_ci        assert_eq!(f.offset(i) + i.len(), f.len());
9286855e09eSopenharmony_ci      }
9296855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for hex_digit"),
9306855e09eSopenharmony_ci    }
9316855e09eSopenharmony_ci    match oct_digit1::<_, (_, ErrorKind)>(f) {
9326855e09eSopenharmony_ci      Ok((i, _)) => {
9336855e09eSopenharmony_ci        assert_eq!(f.offset(i) + i.len(), f.len());
9346855e09eSopenharmony_ci      }
9356855e09eSopenharmony_ci      _ => panic!("wrong return type in offset test for oct_digit"),
9366855e09eSopenharmony_ci    }
9376855e09eSopenharmony_ci  }
9386855e09eSopenharmony_ci
9396855e09eSopenharmony_ci  #[test]
9406855e09eSopenharmony_ci  fn is_not_line_ending_bytes() {
9416855e09eSopenharmony_ci    let a: &[u8] = b"ab12cd\nefgh";
9426855e09eSopenharmony_ci    assert_eq!(
9436855e09eSopenharmony_ci      not_line_ending::<_, (_, ErrorKind)>(a),
9446855e09eSopenharmony_ci      Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
9456855e09eSopenharmony_ci    );
9466855e09eSopenharmony_ci
9476855e09eSopenharmony_ci    let b: &[u8] = b"ab12cd\nefgh\nijkl";
9486855e09eSopenharmony_ci    assert_eq!(
9496855e09eSopenharmony_ci      not_line_ending::<_, (_, ErrorKind)>(b),
9506855e09eSopenharmony_ci      Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..]))
9516855e09eSopenharmony_ci    );
9526855e09eSopenharmony_ci
9536855e09eSopenharmony_ci    let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
9546855e09eSopenharmony_ci    assert_eq!(
9556855e09eSopenharmony_ci      not_line_ending::<_, (_, ErrorKind)>(c),
9566855e09eSopenharmony_ci      Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..]))
9576855e09eSopenharmony_ci    );
9586855e09eSopenharmony_ci
9596855e09eSopenharmony_ci    let d: &[u8] = b"ab12cd";
9606855e09eSopenharmony_ci    assert_eq!(
9616855e09eSopenharmony_ci      not_line_ending::<_, (_, ErrorKind)>(d),
9626855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::Unknown))
9636855e09eSopenharmony_ci    );
9646855e09eSopenharmony_ci  }
9656855e09eSopenharmony_ci
9666855e09eSopenharmony_ci  #[test]
9676855e09eSopenharmony_ci  fn is_not_line_ending_str() {
9686855e09eSopenharmony_ci    /*
9696855e09eSopenharmony_ci    let a: &str = "ab12cd\nefgh";
9706855e09eSopenharmony_ci    assert_eq!(not_line_ending(a), Ok((&"\nefgh"[..], &"ab12cd"[..])));
9716855e09eSopenharmony_ci
9726855e09eSopenharmony_ci    let b: &str = "ab12cd\nefgh\nijkl";
9736855e09eSopenharmony_ci    assert_eq!(not_line_ending(b), Ok((&"\nefgh\nijkl"[..], &"ab12cd"[..])));
9746855e09eSopenharmony_ci
9756855e09eSopenharmony_ci    let c: &str = "ab12cd\r\nefgh\nijkl";
9766855e09eSopenharmony_ci    assert_eq!(not_line_ending(c), Ok((&"\r\nefgh\nijkl"[..], &"ab12cd"[..])));
9776855e09eSopenharmony_ci
9786855e09eSopenharmony_ci    let d = "βèƒôřè\nÂßÇáƒƭèř";
9796855e09eSopenharmony_ci    assert_eq!(not_line_ending(d), Ok((&"\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
9806855e09eSopenharmony_ci
9816855e09eSopenharmony_ci    let e = "βèƒôřè\r\nÂßÇáƒƭèř";
9826855e09eSopenharmony_ci    assert_eq!(not_line_ending(e), Ok((&"\r\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
9836855e09eSopenharmony_ci    */
9846855e09eSopenharmony_ci
9856855e09eSopenharmony_ci    let f = "βèƒôřè\rÂßÇáƒƭèř";
9866855e09eSopenharmony_ci    assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
9876855e09eSopenharmony_ci
9886855e09eSopenharmony_ci    let g2: &str = "ab12cd";
9896855e09eSopenharmony_ci    assert_eq!(
9906855e09eSopenharmony_ci      not_line_ending::<_, (_, ErrorKind)>(g2),
9916855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::Unknown))
9926855e09eSopenharmony_ci    );
9936855e09eSopenharmony_ci  }
9946855e09eSopenharmony_ci
9956855e09eSopenharmony_ci  #[test]
9966855e09eSopenharmony_ci  fn hex_digit_test() {
9976855e09eSopenharmony_ci    let i = &b"0123456789abcdefABCDEF;"[..];
9986855e09eSopenharmony_ci    assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
9996855e09eSopenharmony_ci
10006855e09eSopenharmony_ci    let i = &b"g"[..];
10016855e09eSopenharmony_ci    assert_parse!(
10026855e09eSopenharmony_ci      hex_digit1(i),
10036855e09eSopenharmony_ci      Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
10046855e09eSopenharmony_ci    );
10056855e09eSopenharmony_ci
10066855e09eSopenharmony_ci    let i = &b"G"[..];
10076855e09eSopenharmony_ci    assert_parse!(
10086855e09eSopenharmony_ci      hex_digit1(i),
10096855e09eSopenharmony_ci      Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
10106855e09eSopenharmony_ci    );
10116855e09eSopenharmony_ci
10126855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'0'));
10136855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'9'));
10146855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'a'));
10156855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'f'));
10166855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'A'));
10176855e09eSopenharmony_ci    assert!(crate::character::is_hex_digit(b'F'));
10186855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b'g'));
10196855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b'G'));
10206855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b'/'));
10216855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b':'));
10226855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b'@'));
10236855e09eSopenharmony_ci    assert!(!crate::character::is_hex_digit(b'\x60'));
10246855e09eSopenharmony_ci  }
10256855e09eSopenharmony_ci
10266855e09eSopenharmony_ci  #[test]
10276855e09eSopenharmony_ci  fn oct_digit_test() {
10286855e09eSopenharmony_ci    let i = &b"01234567;"[..];
10296855e09eSopenharmony_ci    assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
10306855e09eSopenharmony_ci
10316855e09eSopenharmony_ci    let i = &b"8"[..];
10326855e09eSopenharmony_ci    assert_parse!(
10336855e09eSopenharmony_ci      oct_digit1(i),
10346855e09eSopenharmony_ci      Err(Err::Error(error_position!(i, ErrorKind::OctDigit)))
10356855e09eSopenharmony_ci    );
10366855e09eSopenharmony_ci
10376855e09eSopenharmony_ci    assert!(crate::character::is_oct_digit(b'0'));
10386855e09eSopenharmony_ci    assert!(crate::character::is_oct_digit(b'7'));
10396855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'8'));
10406855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'9'));
10416855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'a'));
10426855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'A'));
10436855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'/'));
10446855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b':'));
10456855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'@'));
10466855e09eSopenharmony_ci    assert!(!crate::character::is_oct_digit(b'\x60'));
10476855e09eSopenharmony_ci  }
10486855e09eSopenharmony_ci
10496855e09eSopenharmony_ci  #[test]
10506855e09eSopenharmony_ci  fn full_line_windows() {
10516855e09eSopenharmony_ci    fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
10526855e09eSopenharmony_ci      pair(not_line_ending, line_ending)(i)
10536855e09eSopenharmony_ci    }
10546855e09eSopenharmony_ci    let input = b"abc\r\n";
10556855e09eSopenharmony_ci    let output = take_full_line(input);
10566855e09eSopenharmony_ci    assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..]))));
10576855e09eSopenharmony_ci  }
10586855e09eSopenharmony_ci
10596855e09eSopenharmony_ci  #[test]
10606855e09eSopenharmony_ci  fn full_line_unix() {
10616855e09eSopenharmony_ci    fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
10626855e09eSopenharmony_ci      pair(not_line_ending, line_ending)(i)
10636855e09eSopenharmony_ci    }
10646855e09eSopenharmony_ci    let input = b"abc\n";
10656855e09eSopenharmony_ci    let output = take_full_line(input);
10666855e09eSopenharmony_ci    assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..]))));
10676855e09eSopenharmony_ci  }
10686855e09eSopenharmony_ci
10696855e09eSopenharmony_ci  #[test]
10706855e09eSopenharmony_ci  fn check_windows_lineending() {
10716855e09eSopenharmony_ci    let input = b"\r\n";
10726855e09eSopenharmony_ci    let output = line_ending(&input[..]);
10736855e09eSopenharmony_ci    assert_parse!(output, Ok((&b""[..], &b"\r\n"[..])));
10746855e09eSopenharmony_ci  }
10756855e09eSopenharmony_ci
10766855e09eSopenharmony_ci  #[test]
10776855e09eSopenharmony_ci  fn check_unix_lineending() {
10786855e09eSopenharmony_ci    let input = b"\n";
10796855e09eSopenharmony_ci    let output = line_ending(&input[..]);
10806855e09eSopenharmony_ci    assert_parse!(output, Ok((&b""[..], &b"\n"[..])));
10816855e09eSopenharmony_ci  }
10826855e09eSopenharmony_ci
10836855e09eSopenharmony_ci  #[test]
10846855e09eSopenharmony_ci  fn cr_lf() {
10856855e09eSopenharmony_ci    assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
10866855e09eSopenharmony_ci    assert_parse!(crlf(&b"\r"[..]), Err(Err::Incomplete(Needed::new(2))));
10876855e09eSopenharmony_ci    assert_parse!(
10886855e09eSopenharmony_ci      crlf(&b"\ra"[..]),
10896855e09eSopenharmony_ci      Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
10906855e09eSopenharmony_ci    );
10916855e09eSopenharmony_ci
10926855e09eSopenharmony_ci    assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
10936855e09eSopenharmony_ci    assert_parse!(crlf("\r"), Err(Err::Incomplete(Needed::new(2))));
10946855e09eSopenharmony_ci    assert_parse!(
10956855e09eSopenharmony_ci      crlf("\ra"),
10966855e09eSopenharmony_ci      Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
10976855e09eSopenharmony_ci    );
10986855e09eSopenharmony_ci  }
10996855e09eSopenharmony_ci
11006855e09eSopenharmony_ci  #[test]
11016855e09eSopenharmony_ci  fn end_of_line() {
11026855e09eSopenharmony_ci    assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
11036855e09eSopenharmony_ci    assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
11046855e09eSopenharmony_ci    assert_parse!(
11056855e09eSopenharmony_ci      line_ending(&b"\r"[..]),
11066855e09eSopenharmony_ci      Err(Err::Incomplete(Needed::new(2)))
11076855e09eSopenharmony_ci    );
11086855e09eSopenharmony_ci    assert_parse!(
11096855e09eSopenharmony_ci      line_ending(&b"\ra"[..]),
11106855e09eSopenharmony_ci      Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
11116855e09eSopenharmony_ci    );
11126855e09eSopenharmony_ci
11136855e09eSopenharmony_ci    assert_parse!(line_ending("\na"), Ok(("a", "\n")));
11146855e09eSopenharmony_ci    assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
11156855e09eSopenharmony_ci    assert_parse!(line_ending("\r"), Err(Err::Incomplete(Needed::new(2))));
11166855e09eSopenharmony_ci    assert_parse!(
11176855e09eSopenharmony_ci      line_ending("\ra"),
11186855e09eSopenharmony_ci      Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
11196855e09eSopenharmony_ci    );
11206855e09eSopenharmony_ci  }
11216855e09eSopenharmony_ci
11226855e09eSopenharmony_ci  fn digit_to_i16(input: &str) -> IResult<&str, i16> {
11236855e09eSopenharmony_ci    let i = input;
11246855e09eSopenharmony_ci    let (i, opt_sign) = opt(alt((char('+'), char('-'))))(i)?;
11256855e09eSopenharmony_ci    let sign = match opt_sign {
11266855e09eSopenharmony_ci      Some('+') => true,
11276855e09eSopenharmony_ci      Some('-') => false,
11286855e09eSopenharmony_ci      _ => true,
11296855e09eSopenharmony_ci    };
11306855e09eSopenharmony_ci
11316855e09eSopenharmony_ci    let (i, s) = match digit1::<_, crate::error::Error<_>>(i) {
11326855e09eSopenharmony_ci      Ok((i, s)) => (i, s),
11336855e09eSopenharmony_ci      Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
11346855e09eSopenharmony_ci      Err(_) => {
11356855e09eSopenharmony_ci        return Err(Err::Error(crate::error::Error::from_error_kind(
11366855e09eSopenharmony_ci          input,
11376855e09eSopenharmony_ci          ErrorKind::Digit,
11386855e09eSopenharmony_ci        )))
11396855e09eSopenharmony_ci      }
11406855e09eSopenharmony_ci    };
11416855e09eSopenharmony_ci    match s.parse_to() {
11426855e09eSopenharmony_ci      Some(n) => {
11436855e09eSopenharmony_ci        if sign {
11446855e09eSopenharmony_ci          Ok((i, n))
11456855e09eSopenharmony_ci        } else {
11466855e09eSopenharmony_ci          Ok((i, -n))
11476855e09eSopenharmony_ci        }
11486855e09eSopenharmony_ci      }
11496855e09eSopenharmony_ci      None => Err(Err::Error(crate::error::Error::from_error_kind(
11506855e09eSopenharmony_ci        i,
11516855e09eSopenharmony_ci        ErrorKind::Digit,
11526855e09eSopenharmony_ci      ))),
11536855e09eSopenharmony_ci    }
11546855e09eSopenharmony_ci  }
11556855e09eSopenharmony_ci
11566855e09eSopenharmony_ci  fn digit_to_u32(i: &str) -> IResult<&str, u32> {
11576855e09eSopenharmony_ci    let (i, s) = digit1(i)?;
11586855e09eSopenharmony_ci    match s.parse_to() {
11596855e09eSopenharmony_ci      Some(n) => Ok((i, n)),
11606855e09eSopenharmony_ci      None => Err(Err::Error(crate::error::Error::from_error_kind(
11616855e09eSopenharmony_ci        i,
11626855e09eSopenharmony_ci        ErrorKind::Digit,
11636855e09eSopenharmony_ci      ))),
11646855e09eSopenharmony_ci    }
11656855e09eSopenharmony_ci  }
11666855e09eSopenharmony_ci
11676855e09eSopenharmony_ci  proptest! {
11686855e09eSopenharmony_ci    #[test]
11696855e09eSopenharmony_ci    fn ints(s in "\\PC*") {
11706855e09eSopenharmony_ci        let res1 = digit_to_i16(&s);
11716855e09eSopenharmony_ci        let res2 = i16(s.as_str());
11726855e09eSopenharmony_ci        assert_eq!(res1, res2);
11736855e09eSopenharmony_ci    }
11746855e09eSopenharmony_ci
11756855e09eSopenharmony_ci    #[test]
11766855e09eSopenharmony_ci    fn uints(s in "\\PC*") {
11776855e09eSopenharmony_ci        let res1 = digit_to_u32(&s);
11786855e09eSopenharmony_ci        let res2 = u32(s.as_str());
11796855e09eSopenharmony_ci        assert_eq!(res1, res2);
11806855e09eSopenharmony_ci    }
11816855e09eSopenharmony_ci  }
11826855e09eSopenharmony_ci}
1183