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