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