16855e09eSopenharmony_ci//! Parsers recognizing bytes streams, complete input version
26855e09eSopenharmony_ci
36855e09eSopenharmony_ciuse crate::error::ErrorKind;
46855e09eSopenharmony_ciuse crate::error::ParseError;
56855e09eSopenharmony_ciuse crate::internal::{Err, IResult, Parser};
66855e09eSopenharmony_ciuse crate::lib::std::ops::RangeFrom;
76855e09eSopenharmony_ciuse crate::lib::std::result::Result::*;
86855e09eSopenharmony_ciuse crate::traits::{
96855e09eSopenharmony_ci  Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
106855e09eSopenharmony_ci  InputTakeAtPosition, Slice, ToUsize,
116855e09eSopenharmony_ci};
126855e09eSopenharmony_ci
136855e09eSopenharmony_ci/// Recognizes a pattern
146855e09eSopenharmony_ci///
156855e09eSopenharmony_ci/// The input data will be compared to the tag combinator's argument and will return the part of
166855e09eSopenharmony_ci/// the input that matches the argument
176855e09eSopenharmony_ci///
186855e09eSopenharmony_ci/// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern
196855e09eSopenharmony_ci/// # Example
206855e09eSopenharmony_ci/// ```rust
216855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
226855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
236855e09eSopenharmony_ci///
246855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, &str> {
256855e09eSopenharmony_ci///   tag("Hello")(s)
266855e09eSopenharmony_ci/// }
276855e09eSopenharmony_ci///
286855e09eSopenharmony_ci/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
296855e09eSopenharmony_ci/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
306855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag))));
316855e09eSopenharmony_ci/// ```
326855e09eSopenharmony_cipub fn tag<T, Input, Error: ParseError<Input>>(
336855e09eSopenharmony_ci  tag: T,
346855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
356855e09eSopenharmony_ciwhere
366855e09eSopenharmony_ci  Input: InputTake + Compare<T>,
376855e09eSopenharmony_ci  T: InputLength + Clone,
386855e09eSopenharmony_ci{
396855e09eSopenharmony_ci  move |i: Input| {
406855e09eSopenharmony_ci    let tag_len = tag.input_len();
416855e09eSopenharmony_ci    let t = tag.clone();
426855e09eSopenharmony_ci    let res: IResult<_, _, Error> = match i.compare(t) {
436855e09eSopenharmony_ci      CompareResult::Ok => Ok(i.take_split(tag_len)),
446855e09eSopenharmony_ci      _ => {
456855e09eSopenharmony_ci        let e: ErrorKind = ErrorKind::Tag;
466855e09eSopenharmony_ci        Err(Err::Error(Error::from_error_kind(i, e)))
476855e09eSopenharmony_ci      }
486855e09eSopenharmony_ci    };
496855e09eSopenharmony_ci    res
506855e09eSopenharmony_ci  }
516855e09eSopenharmony_ci}
526855e09eSopenharmony_ci
536855e09eSopenharmony_ci/// Recognizes a case insensitive pattern.
546855e09eSopenharmony_ci///
556855e09eSopenharmony_ci/// The input data will be compared to the tag combinator's argument and will return the part of
566855e09eSopenharmony_ci/// the input that matches the argument with no regard to case.
576855e09eSopenharmony_ci///
586855e09eSopenharmony_ci/// It will return `Err(Err::Error((_, ErrorKind::Tag)))` if the input doesn't match the pattern.
596855e09eSopenharmony_ci/// # Example
606855e09eSopenharmony_ci/// ```rust
616855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
626855e09eSopenharmony_ci/// use nom::bytes::complete::tag_no_case;
636855e09eSopenharmony_ci///
646855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, &str> {
656855e09eSopenharmony_ci///   tag_no_case("hello")(s)
666855e09eSopenharmony_ci/// }
676855e09eSopenharmony_ci///
686855e09eSopenharmony_ci/// assert_eq!(parser("Hello, World!"), Ok((", World!", "Hello")));
696855e09eSopenharmony_ci/// assert_eq!(parser("hello, World!"), Ok((", World!", "hello")));
706855e09eSopenharmony_ci/// assert_eq!(parser("HeLlO, World!"), Ok((", World!", "HeLlO")));
716855e09eSopenharmony_ci/// assert_eq!(parser("Something"), Err(Err::Error(Error::new("Something", ErrorKind::Tag))));
726855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag))));
736855e09eSopenharmony_ci/// ```
746855e09eSopenharmony_cipub fn tag_no_case<T, Input, Error: ParseError<Input>>(
756855e09eSopenharmony_ci  tag: T,
766855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
776855e09eSopenharmony_ciwhere
786855e09eSopenharmony_ci  Input: InputTake + Compare<T>,
796855e09eSopenharmony_ci  T: InputLength + Clone,
806855e09eSopenharmony_ci{
816855e09eSopenharmony_ci  move |i: Input| {
826855e09eSopenharmony_ci    let tag_len = tag.input_len();
836855e09eSopenharmony_ci    let t = tag.clone();
846855e09eSopenharmony_ci
856855e09eSopenharmony_ci    let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
866855e09eSopenharmony_ci      CompareResult::Ok => Ok(i.take_split(tag_len)),
876855e09eSopenharmony_ci      _ => {
886855e09eSopenharmony_ci        let e: ErrorKind = ErrorKind::Tag;
896855e09eSopenharmony_ci        Err(Err::Error(Error::from_error_kind(i, e)))
906855e09eSopenharmony_ci      }
916855e09eSopenharmony_ci    };
926855e09eSopenharmony_ci    res
936855e09eSopenharmony_ci  }
946855e09eSopenharmony_ci}
956855e09eSopenharmony_ci
966855e09eSopenharmony_ci/// Parse till certain characters are met.
976855e09eSopenharmony_ci///
986855e09eSopenharmony_ci/// The parser will return the longest slice till one of the characters of the combinator's argument are met.
996855e09eSopenharmony_ci///
1006855e09eSopenharmony_ci/// It doesn't consume the matched character.
1016855e09eSopenharmony_ci///
1026855e09eSopenharmony_ci/// It will return a `Err::Error(("", ErrorKind::IsNot))` if the pattern wasn't met.
1036855e09eSopenharmony_ci/// # Example
1046855e09eSopenharmony_ci/// ```rust
1056855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
1066855e09eSopenharmony_ci/// use nom::bytes::complete::is_not;
1076855e09eSopenharmony_ci///
1086855e09eSopenharmony_ci/// fn not_space(s: &str) -> IResult<&str, &str> {
1096855e09eSopenharmony_ci///   is_not(" \t\r\n")(s)
1106855e09eSopenharmony_ci/// }
1116855e09eSopenharmony_ci///
1126855e09eSopenharmony_ci/// assert_eq!(not_space("Hello, World!"), Ok((" World!", "Hello,")));
1136855e09eSopenharmony_ci/// assert_eq!(not_space("Sometimes\t"), Ok(("\t", "Sometimes")));
1146855e09eSopenharmony_ci/// assert_eq!(not_space("Nospace"), Ok(("", "Nospace")));
1156855e09eSopenharmony_ci/// assert_eq!(not_space(""), Err(Err::Error(Error::new("", ErrorKind::IsNot))));
1166855e09eSopenharmony_ci/// ```
1176855e09eSopenharmony_cipub fn is_not<T, Input, Error: ParseError<Input>>(
1186855e09eSopenharmony_ci  arr: T,
1196855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
1206855e09eSopenharmony_ciwhere
1216855e09eSopenharmony_ci  Input: InputTakeAtPosition,
1226855e09eSopenharmony_ci  T: FindToken<<Input as InputTakeAtPosition>::Item>,
1236855e09eSopenharmony_ci{
1246855e09eSopenharmony_ci  move |i: Input| {
1256855e09eSopenharmony_ci    let e: ErrorKind = ErrorKind::IsNot;
1266855e09eSopenharmony_ci    i.split_at_position1_complete(|c| arr.find_token(c), e)
1276855e09eSopenharmony_ci  }
1286855e09eSopenharmony_ci}
1296855e09eSopenharmony_ci
1306855e09eSopenharmony_ci/// Returns the longest slice of the matches the pattern.
1316855e09eSopenharmony_ci///
1326855e09eSopenharmony_ci/// The parser will return the longest slice consisting of the characters in provided in the
1336855e09eSopenharmony_ci/// combinator's argument.
1346855e09eSopenharmony_ci///
1356855e09eSopenharmony_ci/// It will return a `Err(Err::Error((_, ErrorKind::IsA)))` if the pattern wasn't met.
1366855e09eSopenharmony_ci/// # Example
1376855e09eSopenharmony_ci/// ```rust
1386855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
1396855e09eSopenharmony_ci/// use nom::bytes::complete::is_a;
1406855e09eSopenharmony_ci///
1416855e09eSopenharmony_ci/// fn hex(s: &str) -> IResult<&str, &str> {
1426855e09eSopenharmony_ci///   is_a("1234567890ABCDEF")(s)
1436855e09eSopenharmony_ci/// }
1446855e09eSopenharmony_ci///
1456855e09eSopenharmony_ci/// assert_eq!(hex("123 and voila"), Ok((" and voila", "123")));
1466855e09eSopenharmony_ci/// assert_eq!(hex("DEADBEEF and others"), Ok((" and others", "DEADBEEF")));
1476855e09eSopenharmony_ci/// assert_eq!(hex("BADBABEsomething"), Ok(("something", "BADBABE")));
1486855e09eSopenharmony_ci/// assert_eq!(hex("D15EA5E"), Ok(("", "D15EA5E")));
1496855e09eSopenharmony_ci/// assert_eq!(hex(""), Err(Err::Error(Error::new("", ErrorKind::IsA))));
1506855e09eSopenharmony_ci/// ```
1516855e09eSopenharmony_cipub fn is_a<T, Input, Error: ParseError<Input>>(
1526855e09eSopenharmony_ci  arr: T,
1536855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
1546855e09eSopenharmony_ciwhere
1556855e09eSopenharmony_ci  Input: InputTakeAtPosition,
1566855e09eSopenharmony_ci  T: FindToken<<Input as InputTakeAtPosition>::Item>,
1576855e09eSopenharmony_ci{
1586855e09eSopenharmony_ci  move |i: Input| {
1596855e09eSopenharmony_ci    let e: ErrorKind = ErrorKind::IsA;
1606855e09eSopenharmony_ci    i.split_at_position1_complete(|c| !arr.find_token(c), e)
1616855e09eSopenharmony_ci  }
1626855e09eSopenharmony_ci}
1636855e09eSopenharmony_ci
1646855e09eSopenharmony_ci/// Returns the longest input slice (if any) that matches the predicate.
1656855e09eSopenharmony_ci///
1666855e09eSopenharmony_ci/// The parser will return the longest slice that matches the given predicate *(a function that
1676855e09eSopenharmony_ci/// takes the input and returns a bool)*.
1686855e09eSopenharmony_ci/// # Example
1696855e09eSopenharmony_ci/// ```rust
1706855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult};
1716855e09eSopenharmony_ci/// use nom::bytes::complete::take_while;
1726855e09eSopenharmony_ci/// use nom::character::is_alphabetic;
1736855e09eSopenharmony_ci///
1746855e09eSopenharmony_ci/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
1756855e09eSopenharmony_ci///   take_while(is_alphabetic)(s)
1766855e09eSopenharmony_ci/// }
1776855e09eSopenharmony_ci///
1786855e09eSopenharmony_ci/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
1796855e09eSopenharmony_ci/// assert_eq!(alpha(b"12345"), Ok((&b"12345"[..], &b""[..])));
1806855e09eSopenharmony_ci/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
1816855e09eSopenharmony_ci/// assert_eq!(alpha(b""), Ok((&b""[..], &b""[..])));
1826855e09eSopenharmony_ci/// ```
1836855e09eSopenharmony_cipub fn take_while<F, Input, Error: ParseError<Input>>(
1846855e09eSopenharmony_ci  cond: F,
1856855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
1866855e09eSopenharmony_ciwhere
1876855e09eSopenharmony_ci  Input: InputTakeAtPosition,
1886855e09eSopenharmony_ci  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
1896855e09eSopenharmony_ci{
1906855e09eSopenharmony_ci  move |i: Input| i.split_at_position_complete(|c| !cond(c))
1916855e09eSopenharmony_ci}
1926855e09eSopenharmony_ci
1936855e09eSopenharmony_ci/// Returns the longest (at least 1) input slice that matches the predicate.
1946855e09eSopenharmony_ci///
1956855e09eSopenharmony_ci/// The parser will return the longest slice that matches the given predicate *(a function that
1966855e09eSopenharmony_ci/// takes the input and returns a bool)*.
1976855e09eSopenharmony_ci///
1986855e09eSopenharmony_ci/// It will return an `Err(Err::Error((_, ErrorKind::TakeWhile1)))` if the pattern wasn't met.
1996855e09eSopenharmony_ci/// # Example
2006855e09eSopenharmony_ci/// ```rust
2016855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
2026855e09eSopenharmony_ci/// use nom::bytes::complete::take_while1;
2036855e09eSopenharmony_ci/// use nom::character::is_alphabetic;
2046855e09eSopenharmony_ci///
2056855e09eSopenharmony_ci/// fn alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
2066855e09eSopenharmony_ci///   take_while1(is_alphabetic)(s)
2076855e09eSopenharmony_ci/// }
2086855e09eSopenharmony_ci///
2096855e09eSopenharmony_ci/// assert_eq!(alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
2106855e09eSopenharmony_ci/// assert_eq!(alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
2116855e09eSopenharmony_ci/// assert_eq!(alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhile1))));
2126855e09eSopenharmony_ci/// ```
2136855e09eSopenharmony_cipub fn take_while1<F, Input, Error: ParseError<Input>>(
2146855e09eSopenharmony_ci  cond: F,
2156855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
2166855e09eSopenharmony_ciwhere
2176855e09eSopenharmony_ci  Input: InputTakeAtPosition,
2186855e09eSopenharmony_ci  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
2196855e09eSopenharmony_ci{
2206855e09eSopenharmony_ci  move |i: Input| {
2216855e09eSopenharmony_ci    let e: ErrorKind = ErrorKind::TakeWhile1;
2226855e09eSopenharmony_ci    i.split_at_position1_complete(|c| !cond(c), e)
2236855e09eSopenharmony_ci  }
2246855e09eSopenharmony_ci}
2256855e09eSopenharmony_ci
2266855e09eSopenharmony_ci/// Returns the longest (m <= len <= n) input slice  that matches the predicate.
2276855e09eSopenharmony_ci///
2286855e09eSopenharmony_ci/// The parser will return the longest slice that matches the given predicate *(a function that
2296855e09eSopenharmony_ci/// takes the input and returns a bool)*.
2306855e09eSopenharmony_ci///
2316855e09eSopenharmony_ci/// It will return an `Err::Error((_, ErrorKind::TakeWhileMN))` if the pattern wasn't met or is out
2326855e09eSopenharmony_ci/// of range (m <= len <= n).
2336855e09eSopenharmony_ci/// # Example
2346855e09eSopenharmony_ci/// ```rust
2356855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
2366855e09eSopenharmony_ci/// use nom::bytes::complete::take_while_m_n;
2376855e09eSopenharmony_ci/// use nom::character::is_alphabetic;
2386855e09eSopenharmony_ci///
2396855e09eSopenharmony_ci/// fn short_alpha(s: &[u8]) -> IResult<&[u8], &[u8]> {
2406855e09eSopenharmony_ci///   take_while_m_n(3, 6, is_alphabetic)(s)
2416855e09eSopenharmony_ci/// }
2426855e09eSopenharmony_ci///
2436855e09eSopenharmony_ci/// assert_eq!(short_alpha(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
2446855e09eSopenharmony_ci/// assert_eq!(short_alpha(b"lengthy"), Ok((&b"y"[..], &b"length"[..])));
2456855e09eSopenharmony_ci/// assert_eq!(short_alpha(b"latin"), Ok((&b""[..], &b"latin"[..])));
2466855e09eSopenharmony_ci/// assert_eq!(short_alpha(b"ed"), Err(Err::Error(Error::new(&b"ed"[..], ErrorKind::TakeWhileMN))));
2476855e09eSopenharmony_ci/// assert_eq!(short_alpha(b"12345"), Err(Err::Error(Error::new(&b"12345"[..], ErrorKind::TakeWhileMN))));
2486855e09eSopenharmony_ci/// ```
2496855e09eSopenharmony_cipub fn take_while_m_n<F, Input, Error: ParseError<Input>>(
2506855e09eSopenharmony_ci  m: usize,
2516855e09eSopenharmony_ci  n: usize,
2526855e09eSopenharmony_ci  cond: F,
2536855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
2546855e09eSopenharmony_ciwhere
2556855e09eSopenharmony_ci  Input: InputTake + InputIter + InputLength + Slice<RangeFrom<usize>>,
2566855e09eSopenharmony_ci  F: Fn(<Input as InputIter>::Item) -> bool,
2576855e09eSopenharmony_ci{
2586855e09eSopenharmony_ci  move |i: Input| {
2596855e09eSopenharmony_ci    let input = i;
2606855e09eSopenharmony_ci
2616855e09eSopenharmony_ci    match input.position(|c| !cond(c)) {
2626855e09eSopenharmony_ci      Some(idx) => {
2636855e09eSopenharmony_ci        if idx >= m {
2646855e09eSopenharmony_ci          if idx <= n {
2656855e09eSopenharmony_ci            let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(idx) {
2666855e09eSopenharmony_ci              Ok(input.take_split(index))
2676855e09eSopenharmony_ci            } else {
2686855e09eSopenharmony_ci              Err(Err::Error(Error::from_error_kind(
2696855e09eSopenharmony_ci                input,
2706855e09eSopenharmony_ci                ErrorKind::TakeWhileMN,
2716855e09eSopenharmony_ci              )))
2726855e09eSopenharmony_ci            };
2736855e09eSopenharmony_ci            res
2746855e09eSopenharmony_ci          } else {
2756855e09eSopenharmony_ci            let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(n) {
2766855e09eSopenharmony_ci              Ok(input.take_split(index))
2776855e09eSopenharmony_ci            } else {
2786855e09eSopenharmony_ci              Err(Err::Error(Error::from_error_kind(
2796855e09eSopenharmony_ci                input,
2806855e09eSopenharmony_ci                ErrorKind::TakeWhileMN,
2816855e09eSopenharmony_ci              )))
2826855e09eSopenharmony_ci            };
2836855e09eSopenharmony_ci            res
2846855e09eSopenharmony_ci          }
2856855e09eSopenharmony_ci        } else {
2866855e09eSopenharmony_ci          let e = ErrorKind::TakeWhileMN;
2876855e09eSopenharmony_ci          Err(Err::Error(Error::from_error_kind(input, e)))
2886855e09eSopenharmony_ci        }
2896855e09eSopenharmony_ci      }
2906855e09eSopenharmony_ci      None => {
2916855e09eSopenharmony_ci        let len = input.input_len();
2926855e09eSopenharmony_ci        if len >= n {
2936855e09eSopenharmony_ci          match input.slice_index(n) {
2946855e09eSopenharmony_ci            Ok(index) => Ok(input.take_split(index)),
2956855e09eSopenharmony_ci            Err(_needed) => Err(Err::Error(Error::from_error_kind(
2966855e09eSopenharmony_ci              input,
2976855e09eSopenharmony_ci              ErrorKind::TakeWhileMN,
2986855e09eSopenharmony_ci            ))),
2996855e09eSopenharmony_ci          }
3006855e09eSopenharmony_ci        } else if len >= m && len <= n {
3016855e09eSopenharmony_ci          let res: IResult<_, _, Error> = Ok((input.slice(len..), input));
3026855e09eSopenharmony_ci          res
3036855e09eSopenharmony_ci        } else {
3046855e09eSopenharmony_ci          let e = ErrorKind::TakeWhileMN;
3056855e09eSopenharmony_ci          Err(Err::Error(Error::from_error_kind(input, e)))
3066855e09eSopenharmony_ci        }
3076855e09eSopenharmony_ci      }
3086855e09eSopenharmony_ci    }
3096855e09eSopenharmony_ci  }
3106855e09eSopenharmony_ci}
3116855e09eSopenharmony_ci
3126855e09eSopenharmony_ci/// Returns the longest input slice (if any) till a predicate is met.
3136855e09eSopenharmony_ci///
3146855e09eSopenharmony_ci/// The parser will return the longest slice till the given predicate *(a function that
3156855e09eSopenharmony_ci/// takes the input and returns a bool)*.
3166855e09eSopenharmony_ci/// # Example
3176855e09eSopenharmony_ci/// ```rust
3186855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult};
3196855e09eSopenharmony_ci/// use nom::bytes::complete::take_till;
3206855e09eSopenharmony_ci///
3216855e09eSopenharmony_ci/// fn till_colon(s: &str) -> IResult<&str, &str> {
3226855e09eSopenharmony_ci///   take_till(|c| c == ':')(s)
3236855e09eSopenharmony_ci/// }
3246855e09eSopenharmony_ci///
3256855e09eSopenharmony_ci/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
3266855e09eSopenharmony_ci/// assert_eq!(till_colon(":empty matched"), Ok((":empty matched", ""))); //allowed
3276855e09eSopenharmony_ci/// assert_eq!(till_colon("12345"), Ok(("", "12345")));
3286855e09eSopenharmony_ci/// assert_eq!(till_colon(""), Ok(("", "")));
3296855e09eSopenharmony_ci/// ```
3306855e09eSopenharmony_cipub fn take_till<F, Input, Error: ParseError<Input>>(
3316855e09eSopenharmony_ci  cond: F,
3326855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
3336855e09eSopenharmony_ciwhere
3346855e09eSopenharmony_ci  Input: InputTakeAtPosition,
3356855e09eSopenharmony_ci  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
3366855e09eSopenharmony_ci{
3376855e09eSopenharmony_ci  move |i: Input| i.split_at_position_complete(|c| cond(c))
3386855e09eSopenharmony_ci}
3396855e09eSopenharmony_ci
3406855e09eSopenharmony_ci/// Returns the longest (at least 1) input slice till a predicate is met.
3416855e09eSopenharmony_ci///
3426855e09eSopenharmony_ci/// The parser will return the longest slice till the given predicate *(a function that
3436855e09eSopenharmony_ci/// takes the input and returns a bool)*.
3446855e09eSopenharmony_ci///
3456855e09eSopenharmony_ci/// It will return `Err(Err::Error((_, ErrorKind::TakeTill1)))` if the input is empty or the
3466855e09eSopenharmony_ci/// predicate matches the first input.
3476855e09eSopenharmony_ci/// # Example
3486855e09eSopenharmony_ci/// ```rust
3496855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
3506855e09eSopenharmony_ci/// use nom::bytes::complete::take_till1;
3516855e09eSopenharmony_ci///
3526855e09eSopenharmony_ci/// fn till_colon(s: &str) -> IResult<&str, &str> {
3536855e09eSopenharmony_ci///   take_till1(|c| c == ':')(s)
3546855e09eSopenharmony_ci/// }
3556855e09eSopenharmony_ci///
3566855e09eSopenharmony_ci/// assert_eq!(till_colon("latin:123"), Ok((":123", "latin")));
3576855e09eSopenharmony_ci/// assert_eq!(till_colon(":empty matched"), Err(Err::Error(Error::new(":empty matched", ErrorKind::TakeTill1))));
3586855e09eSopenharmony_ci/// assert_eq!(till_colon("12345"), Ok(("", "12345")));
3596855e09eSopenharmony_ci/// assert_eq!(till_colon(""), Err(Err::Error(Error::new("", ErrorKind::TakeTill1))));
3606855e09eSopenharmony_ci/// ```
3616855e09eSopenharmony_cipub fn take_till1<F, Input, Error: ParseError<Input>>(
3626855e09eSopenharmony_ci  cond: F,
3636855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
3646855e09eSopenharmony_ciwhere
3656855e09eSopenharmony_ci  Input: InputTakeAtPosition,
3666855e09eSopenharmony_ci  F: Fn(<Input as InputTakeAtPosition>::Item) -> bool,
3676855e09eSopenharmony_ci{
3686855e09eSopenharmony_ci  move |i: Input| {
3696855e09eSopenharmony_ci    let e: ErrorKind = ErrorKind::TakeTill1;
3706855e09eSopenharmony_ci    i.split_at_position1_complete(|c| cond(c), e)
3716855e09eSopenharmony_ci  }
3726855e09eSopenharmony_ci}
3736855e09eSopenharmony_ci
3746855e09eSopenharmony_ci/// Returns an input slice containing the first N input elements (Input[..N]).
3756855e09eSopenharmony_ci///
3766855e09eSopenharmony_ci/// It will return `Err(Err::Error((_, ErrorKind::Eof)))` if the input is shorter than the argument.
3776855e09eSopenharmony_ci/// # Example
3786855e09eSopenharmony_ci/// ```rust
3796855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
3806855e09eSopenharmony_ci/// use nom::bytes::complete::take;
3816855e09eSopenharmony_ci///
3826855e09eSopenharmony_ci/// fn take6(s: &str) -> IResult<&str, &str> {
3836855e09eSopenharmony_ci///   take(6usize)(s)
3846855e09eSopenharmony_ci/// }
3856855e09eSopenharmony_ci///
3866855e09eSopenharmony_ci/// assert_eq!(take6("1234567"), Ok(("7", "123456")));
3876855e09eSopenharmony_ci/// assert_eq!(take6("things"), Ok(("", "things")));
3886855e09eSopenharmony_ci/// assert_eq!(take6("short"), Err(Err::Error(Error::new("short", ErrorKind::Eof))));
3896855e09eSopenharmony_ci/// assert_eq!(take6(""), Err(Err::Error(Error::new("", ErrorKind::Eof))));
3906855e09eSopenharmony_ci/// ```
3916855e09eSopenharmony_ci///
3926855e09eSopenharmony_ci/// The units that are taken will depend on the input type. For example, for a
3936855e09eSopenharmony_ci/// `&str` it will take a number of `char`'s, whereas for a `&[u8]` it will
3946855e09eSopenharmony_ci/// take that many `u8`'s:
3956855e09eSopenharmony_ci///
3966855e09eSopenharmony_ci/// ```rust
3976855e09eSopenharmony_ci/// use nom::error::Error;
3986855e09eSopenharmony_ci/// use nom::bytes::complete::take;
3996855e09eSopenharmony_ci///
4006855e09eSopenharmony_ci/// assert_eq!(take::<_, _, Error<_>>(1usize)("�"), Ok(("", "�")));
4016855e09eSopenharmony_ci/// assert_eq!(take::<_, _, Error<_>>(1usize)("�".as_bytes()), Ok((b"\x9F\x92\x99".as_ref(), b"\xF0".as_ref())));
4026855e09eSopenharmony_ci/// ```
4036855e09eSopenharmony_cipub fn take<C, Input, Error: ParseError<Input>>(
4046855e09eSopenharmony_ci  count: C,
4056855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
4066855e09eSopenharmony_ciwhere
4076855e09eSopenharmony_ci  Input: InputIter + InputTake,
4086855e09eSopenharmony_ci  C: ToUsize,
4096855e09eSopenharmony_ci{
4106855e09eSopenharmony_ci  let c = count.to_usize();
4116855e09eSopenharmony_ci  move |i: Input| match i.slice_index(c) {
4126855e09eSopenharmony_ci    Err(_needed) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Eof))),
4136855e09eSopenharmony_ci    Ok(index) => Ok(i.take_split(index)),
4146855e09eSopenharmony_ci  }
4156855e09eSopenharmony_ci}
4166855e09eSopenharmony_ci
4176855e09eSopenharmony_ci/// Returns the input slice up to the first occurrence of the pattern.
4186855e09eSopenharmony_ci///
4196855e09eSopenharmony_ci/// It doesn't consume the pattern. It will return `Err(Err::Error((_, ErrorKind::TakeUntil)))`
4206855e09eSopenharmony_ci/// if the pattern wasn't met.
4216855e09eSopenharmony_ci/// # Example
4226855e09eSopenharmony_ci/// ```rust
4236855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
4246855e09eSopenharmony_ci/// use nom::bytes::complete::take_until;
4256855e09eSopenharmony_ci///
4266855e09eSopenharmony_ci/// fn until_eof(s: &str) -> IResult<&str, &str> {
4276855e09eSopenharmony_ci///   take_until("eof")(s)
4286855e09eSopenharmony_ci/// }
4296855e09eSopenharmony_ci///
4306855e09eSopenharmony_ci/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
4316855e09eSopenharmony_ci/// assert_eq!(until_eof("hello, world"), Err(Err::Error(Error::new("hello, world", ErrorKind::TakeUntil))));
4326855e09eSopenharmony_ci/// assert_eq!(until_eof(""), Err(Err::Error(Error::new("", ErrorKind::TakeUntil))));
4336855e09eSopenharmony_ci/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
4346855e09eSopenharmony_ci/// ```
4356855e09eSopenharmony_cipub fn take_until<T, Input, Error: ParseError<Input>>(
4366855e09eSopenharmony_ci  tag: T,
4376855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
4386855e09eSopenharmony_ciwhere
4396855e09eSopenharmony_ci  Input: InputTake + FindSubstring<T>,
4406855e09eSopenharmony_ci  T: InputLength + Clone,
4416855e09eSopenharmony_ci{
4426855e09eSopenharmony_ci  move |i: Input| {
4436855e09eSopenharmony_ci    let t = tag.clone();
4446855e09eSopenharmony_ci    let res: IResult<_, _, Error> = match i.find_substring(t) {
4456855e09eSopenharmony_ci      None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
4466855e09eSopenharmony_ci      Some(index) => Ok(i.take_split(index)),
4476855e09eSopenharmony_ci    };
4486855e09eSopenharmony_ci    res
4496855e09eSopenharmony_ci  }
4506855e09eSopenharmony_ci}
4516855e09eSopenharmony_ci
4526855e09eSopenharmony_ci/// Returns the non empty input slice up to the first occurrence of the pattern.
4536855e09eSopenharmony_ci///
4546855e09eSopenharmony_ci/// It doesn't consume the pattern. It will return `Err(Err::Error((_, ErrorKind::TakeUntil)))`
4556855e09eSopenharmony_ci/// if the pattern wasn't met.
4566855e09eSopenharmony_ci/// # Example
4576855e09eSopenharmony_ci/// ```rust
4586855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult};
4596855e09eSopenharmony_ci/// use nom::bytes::complete::take_until1;
4606855e09eSopenharmony_ci///
4616855e09eSopenharmony_ci/// fn until_eof(s: &str) -> IResult<&str, &str> {
4626855e09eSopenharmony_ci///   take_until1("eof")(s)
4636855e09eSopenharmony_ci/// }
4646855e09eSopenharmony_ci///
4656855e09eSopenharmony_ci/// assert_eq!(until_eof("hello, worldeof"), Ok(("eof", "hello, world")));
4666855e09eSopenharmony_ci/// assert_eq!(until_eof("hello, world"), Err(Err::Error(Error::new("hello, world", ErrorKind::TakeUntil))));
4676855e09eSopenharmony_ci/// assert_eq!(until_eof(""), Err(Err::Error(Error::new("", ErrorKind::TakeUntil))));
4686855e09eSopenharmony_ci/// assert_eq!(until_eof("1eof2eof"), Ok(("eof2eof", "1")));
4696855e09eSopenharmony_ci/// assert_eq!(until_eof("eof"), Err(Err::Error(Error::new("eof", ErrorKind::TakeUntil))));
4706855e09eSopenharmony_ci/// ```
4716855e09eSopenharmony_cipub fn take_until1<T, Input, Error: ParseError<Input>>(
4726855e09eSopenharmony_ci  tag: T,
4736855e09eSopenharmony_ci) -> impl Fn(Input) -> IResult<Input, Input, Error>
4746855e09eSopenharmony_ciwhere
4756855e09eSopenharmony_ci  Input: InputTake + FindSubstring<T>,
4766855e09eSopenharmony_ci  T: InputLength + Clone,
4776855e09eSopenharmony_ci{
4786855e09eSopenharmony_ci  move |i: Input| {
4796855e09eSopenharmony_ci    let t = tag.clone();
4806855e09eSopenharmony_ci    let res: IResult<_, _, Error> = match i.find_substring(t) {
4816855e09eSopenharmony_ci      None => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
4826855e09eSopenharmony_ci      Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
4836855e09eSopenharmony_ci      Some(index) => Ok(i.take_split(index)),
4846855e09eSopenharmony_ci    };
4856855e09eSopenharmony_ci    res
4866855e09eSopenharmony_ci  }
4876855e09eSopenharmony_ci}
4886855e09eSopenharmony_ci
4896855e09eSopenharmony_ci/// Matches a byte string with escaped characters.
4906855e09eSopenharmony_ci///
4916855e09eSopenharmony_ci/// * The first argument matches the normal characters (it must not accept the control character)
4926855e09eSopenharmony_ci/// * The second argument is the control character (like `\` in most languages)
4936855e09eSopenharmony_ci/// * The third argument matches the escaped characters
4946855e09eSopenharmony_ci/// # Example
4956855e09eSopenharmony_ci/// ```
4966855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult};
4976855e09eSopenharmony_ci/// # use nom::character::complete::digit1;
4986855e09eSopenharmony_ci/// use nom::bytes::complete::escaped;
4996855e09eSopenharmony_ci/// use nom::character::complete::one_of;
5006855e09eSopenharmony_ci///
5016855e09eSopenharmony_ci/// fn esc(s: &str) -> IResult<&str, &str> {
5026855e09eSopenharmony_ci///   escaped(digit1, '\\', one_of(r#""n\"#))(s)
5036855e09eSopenharmony_ci/// }
5046855e09eSopenharmony_ci///
5056855e09eSopenharmony_ci/// assert_eq!(esc("123;"), Ok((";", "123")));
5066855e09eSopenharmony_ci/// assert_eq!(esc(r#"12\"34;"#), Ok((";", r#"12\"34"#)));
5076855e09eSopenharmony_ci/// ```
5086855e09eSopenharmony_ci///
5096855e09eSopenharmony_cipub fn escaped<'a, Input: 'a, Error, F, G, O1, O2>(
5106855e09eSopenharmony_ci  mut normal: F,
5116855e09eSopenharmony_ci  control_char: char,
5126855e09eSopenharmony_ci  mut escapable: G,
5136855e09eSopenharmony_ci) -> impl FnMut(Input) -> IResult<Input, Input, Error>
5146855e09eSopenharmony_ciwhere
5156855e09eSopenharmony_ci  Input: Clone
5166855e09eSopenharmony_ci    + crate::traits::Offset
5176855e09eSopenharmony_ci    + InputLength
5186855e09eSopenharmony_ci    + InputTake
5196855e09eSopenharmony_ci    + InputTakeAtPosition
5206855e09eSopenharmony_ci    + Slice<RangeFrom<usize>>
5216855e09eSopenharmony_ci    + InputIter,
5226855e09eSopenharmony_ci  <Input as InputIter>::Item: crate::traits::AsChar,
5236855e09eSopenharmony_ci  F: Parser<Input, O1, Error>,
5246855e09eSopenharmony_ci  G: Parser<Input, O2, Error>,
5256855e09eSopenharmony_ci  Error: ParseError<Input>,
5266855e09eSopenharmony_ci{
5276855e09eSopenharmony_ci  use crate::traits::AsChar;
5286855e09eSopenharmony_ci
5296855e09eSopenharmony_ci  move |input: Input| {
5306855e09eSopenharmony_ci    let mut i = input.clone();
5316855e09eSopenharmony_ci
5326855e09eSopenharmony_ci    while i.input_len() > 0 {
5336855e09eSopenharmony_ci      let current_len = i.input_len();
5346855e09eSopenharmony_ci
5356855e09eSopenharmony_ci      match normal.parse(i.clone()) {
5366855e09eSopenharmony_ci        Ok((i2, _)) => {
5376855e09eSopenharmony_ci          // return if we consumed everything or if the normal parser
5386855e09eSopenharmony_ci          // does not consume anything
5396855e09eSopenharmony_ci          if i2.input_len() == 0 {
5406855e09eSopenharmony_ci            return Ok((input.slice(input.input_len()..), input));
5416855e09eSopenharmony_ci          } else if i2.input_len() == current_len {
5426855e09eSopenharmony_ci            let index = input.offset(&i2);
5436855e09eSopenharmony_ci            return Ok(input.take_split(index));
5446855e09eSopenharmony_ci          } else {
5456855e09eSopenharmony_ci            i = i2;
5466855e09eSopenharmony_ci          }
5476855e09eSopenharmony_ci        }
5486855e09eSopenharmony_ci        Err(Err::Error(_)) => {
5496855e09eSopenharmony_ci          // unwrap() should be safe here since index < $i.input_len()
5506855e09eSopenharmony_ci          if i.iter_elements().next().unwrap().as_char() == control_char {
5516855e09eSopenharmony_ci            let next = control_char.len_utf8();
5526855e09eSopenharmony_ci            if next >= i.input_len() {
5536855e09eSopenharmony_ci              return Err(Err::Error(Error::from_error_kind(
5546855e09eSopenharmony_ci                input,
5556855e09eSopenharmony_ci                ErrorKind::Escaped,
5566855e09eSopenharmony_ci              )));
5576855e09eSopenharmony_ci            } else {
5586855e09eSopenharmony_ci              match escapable.parse(i.slice(next..)) {
5596855e09eSopenharmony_ci                Ok((i2, _)) => {
5606855e09eSopenharmony_ci                  if i2.input_len() == 0 {
5616855e09eSopenharmony_ci                    return Ok((input.slice(input.input_len()..), input));
5626855e09eSopenharmony_ci                  } else {
5636855e09eSopenharmony_ci                    i = i2;
5646855e09eSopenharmony_ci                  }
5656855e09eSopenharmony_ci                }
5666855e09eSopenharmony_ci                Err(e) => return Err(e),
5676855e09eSopenharmony_ci              }
5686855e09eSopenharmony_ci            }
5696855e09eSopenharmony_ci          } else {
5706855e09eSopenharmony_ci            let index = input.offset(&i);
5716855e09eSopenharmony_ci            if index == 0 {
5726855e09eSopenharmony_ci              return Err(Err::Error(Error::from_error_kind(
5736855e09eSopenharmony_ci                input,
5746855e09eSopenharmony_ci                ErrorKind::Escaped,
5756855e09eSopenharmony_ci              )));
5766855e09eSopenharmony_ci            }
5776855e09eSopenharmony_ci            return Ok(input.take_split(index));
5786855e09eSopenharmony_ci          }
5796855e09eSopenharmony_ci        }
5806855e09eSopenharmony_ci        Err(e) => {
5816855e09eSopenharmony_ci          return Err(e);
5826855e09eSopenharmony_ci        }
5836855e09eSopenharmony_ci      }
5846855e09eSopenharmony_ci    }
5856855e09eSopenharmony_ci
5866855e09eSopenharmony_ci    Ok((input.slice(input.input_len()..), input))
5876855e09eSopenharmony_ci  }
5886855e09eSopenharmony_ci}
5896855e09eSopenharmony_ci
5906855e09eSopenharmony_ci/// Matches a byte string with escaped characters.
5916855e09eSopenharmony_ci///
5926855e09eSopenharmony_ci/// * The first argument matches the normal characters (it must not match the control character)
5936855e09eSopenharmony_ci/// * The second argument is the control character (like `\` in most languages)
5946855e09eSopenharmony_ci/// * The third argument matches the escaped characters and transforms them
5956855e09eSopenharmony_ci///
5966855e09eSopenharmony_ci/// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
5976855e09eSopenharmony_ci///
5986855e09eSopenharmony_ci/// ```
5996855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult};
6006855e09eSopenharmony_ci/// # use std::str::from_utf8;
6016855e09eSopenharmony_ci/// use nom::bytes::complete::{escaped_transform, tag};
6026855e09eSopenharmony_ci/// use nom::character::complete::alpha1;
6036855e09eSopenharmony_ci/// use nom::branch::alt;
6046855e09eSopenharmony_ci/// use nom::combinator::value;
6056855e09eSopenharmony_ci///
6066855e09eSopenharmony_ci/// fn parser(input: &str) -> IResult<&str, String> {
6076855e09eSopenharmony_ci///   escaped_transform(
6086855e09eSopenharmony_ci///     alpha1,
6096855e09eSopenharmony_ci///     '\\',
6106855e09eSopenharmony_ci///     alt((
6116855e09eSopenharmony_ci///       value("\\", tag("\\")),
6126855e09eSopenharmony_ci///       value("\"", tag("\"")),
6136855e09eSopenharmony_ci///       value("\n", tag("n")),
6146855e09eSopenharmony_ci///     ))
6156855e09eSopenharmony_ci///   )(input)
6166855e09eSopenharmony_ci/// }
6176855e09eSopenharmony_ci///
6186855e09eSopenharmony_ci/// assert_eq!(parser("ab\\\"cd"), Ok(("", String::from("ab\"cd"))));
6196855e09eSopenharmony_ci/// assert_eq!(parser("ab\\ncd"), Ok(("", String::from("ab\ncd"))));
6206855e09eSopenharmony_ci/// ```
6216855e09eSopenharmony_ci#[cfg(feature = "alloc")]
6226855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
6236855e09eSopenharmony_cipub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
6246855e09eSopenharmony_ci  mut normal: F,
6256855e09eSopenharmony_ci  control_char: char,
6266855e09eSopenharmony_ci  mut transform: G,
6276855e09eSopenharmony_ci) -> impl FnMut(Input) -> IResult<Input, Output, Error>
6286855e09eSopenharmony_ciwhere
6296855e09eSopenharmony_ci  Input: Clone
6306855e09eSopenharmony_ci    + crate::traits::Offset
6316855e09eSopenharmony_ci    + InputLength
6326855e09eSopenharmony_ci    + InputTake
6336855e09eSopenharmony_ci    + InputTakeAtPosition
6346855e09eSopenharmony_ci    + Slice<RangeFrom<usize>>
6356855e09eSopenharmony_ci    + InputIter,
6366855e09eSopenharmony_ci  Input: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
6376855e09eSopenharmony_ci  O1: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
6386855e09eSopenharmony_ci  O2: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
6396855e09eSopenharmony_ci  <Input as InputIter>::Item: crate::traits::AsChar,
6406855e09eSopenharmony_ci  F: Parser<Input, O1, Error>,
6416855e09eSopenharmony_ci  G: Parser<Input, O2, Error>,
6426855e09eSopenharmony_ci  Error: ParseError<Input>,
6436855e09eSopenharmony_ci{
6446855e09eSopenharmony_ci  use crate::traits::AsChar;
6456855e09eSopenharmony_ci
6466855e09eSopenharmony_ci  move |input: Input| {
6476855e09eSopenharmony_ci    let mut index = 0;
6486855e09eSopenharmony_ci    let mut res = input.new_builder();
6496855e09eSopenharmony_ci
6506855e09eSopenharmony_ci    let i = input.clone();
6516855e09eSopenharmony_ci
6526855e09eSopenharmony_ci    while index < i.input_len() {
6536855e09eSopenharmony_ci      let current_len = i.input_len();
6546855e09eSopenharmony_ci      let remainder = i.slice(index..);
6556855e09eSopenharmony_ci      match normal.parse(remainder.clone()) {
6566855e09eSopenharmony_ci        Ok((i2, o)) => {
6576855e09eSopenharmony_ci          o.extend_into(&mut res);
6586855e09eSopenharmony_ci          if i2.input_len() == 0 {
6596855e09eSopenharmony_ci            return Ok((i.slice(i.input_len()..), res));
6606855e09eSopenharmony_ci          } else if i2.input_len() == current_len {
6616855e09eSopenharmony_ci            return Ok((remainder, res));
6626855e09eSopenharmony_ci          } else {
6636855e09eSopenharmony_ci            index = input.offset(&i2);
6646855e09eSopenharmony_ci          }
6656855e09eSopenharmony_ci        }
6666855e09eSopenharmony_ci        Err(Err::Error(_)) => {
6676855e09eSopenharmony_ci          // unwrap() should be safe here since index < $i.input_len()
6686855e09eSopenharmony_ci          if remainder.iter_elements().next().unwrap().as_char() == control_char {
6696855e09eSopenharmony_ci            let next = index + control_char.len_utf8();
6706855e09eSopenharmony_ci            let input_len = input.input_len();
6716855e09eSopenharmony_ci
6726855e09eSopenharmony_ci            if next >= input_len {
6736855e09eSopenharmony_ci              return Err(Err::Error(Error::from_error_kind(
6746855e09eSopenharmony_ci                remainder,
6756855e09eSopenharmony_ci                ErrorKind::EscapedTransform,
6766855e09eSopenharmony_ci              )));
6776855e09eSopenharmony_ci            } else {
6786855e09eSopenharmony_ci              match transform.parse(i.slice(next..)) {
6796855e09eSopenharmony_ci                Ok((i2, o)) => {
6806855e09eSopenharmony_ci                  o.extend_into(&mut res);
6816855e09eSopenharmony_ci                  if i2.input_len() == 0 {
6826855e09eSopenharmony_ci                    return Ok((i.slice(i.input_len()..), res));
6836855e09eSopenharmony_ci                  } else {
6846855e09eSopenharmony_ci                    index = input.offset(&i2);
6856855e09eSopenharmony_ci                  }
6866855e09eSopenharmony_ci                }
6876855e09eSopenharmony_ci                Err(e) => return Err(e),
6886855e09eSopenharmony_ci              }
6896855e09eSopenharmony_ci            }
6906855e09eSopenharmony_ci          } else {
6916855e09eSopenharmony_ci            if index == 0 {
6926855e09eSopenharmony_ci              return Err(Err::Error(Error::from_error_kind(
6936855e09eSopenharmony_ci                remainder,
6946855e09eSopenharmony_ci                ErrorKind::EscapedTransform,
6956855e09eSopenharmony_ci              )));
6966855e09eSopenharmony_ci            }
6976855e09eSopenharmony_ci            return Ok((remainder, res));
6986855e09eSopenharmony_ci          }
6996855e09eSopenharmony_ci        }
7006855e09eSopenharmony_ci        Err(e) => return Err(e),
7016855e09eSopenharmony_ci      }
7026855e09eSopenharmony_ci    }
7036855e09eSopenharmony_ci    Ok((input.slice(index..), res))
7046855e09eSopenharmony_ci  }
7056855e09eSopenharmony_ci}
7066855e09eSopenharmony_ci
7076855e09eSopenharmony_ci#[cfg(test)]
7086855e09eSopenharmony_cimod tests {
7096855e09eSopenharmony_ci  use super::*;
7106855e09eSopenharmony_ci
7116855e09eSopenharmony_ci  #[test]
7126855e09eSopenharmony_ci  fn complete_take_while_m_n_utf8_all_matching() {
7136855e09eSopenharmony_ci    let result: IResult<&str, &str> =
7146855e09eSopenharmony_ci      super::take_while_m_n(1, 4, |c: char| c.is_alphabetic())("øn");
7156855e09eSopenharmony_ci    assert_eq!(result, Ok(("", "øn")));
7166855e09eSopenharmony_ci  }
7176855e09eSopenharmony_ci
7186855e09eSopenharmony_ci  #[test]
7196855e09eSopenharmony_ci  fn complete_take_while_m_n_utf8_all_matching_substring() {
7206855e09eSopenharmony_ci    let result: IResult<&str, &str> =
7216855e09eSopenharmony_ci      super::take_while_m_n(1, 1, |c: char| c.is_alphabetic())("øn");
7226855e09eSopenharmony_ci    assert_eq!(result, Ok(("n", "ø")));
7236855e09eSopenharmony_ci  }
7246855e09eSopenharmony_ci
7256855e09eSopenharmony_ci  // issue #1336 "escaped hangs if normal parser accepts empty"
7266855e09eSopenharmony_ci  fn escaped_string(input: &str) -> IResult<&str, &str> {
7276855e09eSopenharmony_ci    use crate::character::complete::{alpha0, one_of};
7286855e09eSopenharmony_ci    escaped(alpha0, '\\', one_of("n"))(input)
7296855e09eSopenharmony_ci  }
7306855e09eSopenharmony_ci
7316855e09eSopenharmony_ci  // issue #1336 "escaped hangs if normal parser accepts empty"
7326855e09eSopenharmony_ci  #[test]
7336855e09eSopenharmony_ci  fn escaped_hang() {
7346855e09eSopenharmony_ci    escaped_string("7").unwrap();
7356855e09eSopenharmony_ci    escaped_string("a7").unwrap();
7366855e09eSopenharmony_ci  }
7376855e09eSopenharmony_ci
7386855e09eSopenharmony_ci  // issue ##1118 escaped does not work with empty string
7396855e09eSopenharmony_ci  fn unquote<'a>(input: &'a str) -> IResult<&'a str, &'a str> {
7406855e09eSopenharmony_ci    use crate::bytes::complete::*;
7416855e09eSopenharmony_ci    use crate::character::complete::*;
7426855e09eSopenharmony_ci    use crate::combinator::opt;
7436855e09eSopenharmony_ci    use crate::sequence::delimited;
7446855e09eSopenharmony_ci
7456855e09eSopenharmony_ci    delimited(
7466855e09eSopenharmony_ci      char('"'),
7476855e09eSopenharmony_ci      escaped(opt(none_of(r#"\""#)), '\\', one_of(r#"\"rnt"#)),
7486855e09eSopenharmony_ci      char('"'),
7496855e09eSopenharmony_ci    )(input)
7506855e09eSopenharmony_ci  }
7516855e09eSopenharmony_ci
7526855e09eSopenharmony_ci  #[test]
7536855e09eSopenharmony_ci  fn escaped_hang_1118() {
7546855e09eSopenharmony_ci    assert_eq!(unquote(r#""""#), Ok(("", "")));
7556855e09eSopenharmony_ci  }
7566855e09eSopenharmony_ci}
757