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