16855e09eSopenharmony_ci//! Combinators applying their child parser multiple times 26855e09eSopenharmony_ci 36855e09eSopenharmony_ci#[cfg(test)] 46855e09eSopenharmony_cimod tests; 56855e09eSopenharmony_ci 66855e09eSopenharmony_ciuse crate::error::ErrorKind; 76855e09eSopenharmony_ciuse crate::error::ParseError; 86855e09eSopenharmony_ciuse crate::internal::{Err, IResult, Needed, Parser}; 96855e09eSopenharmony_ci#[cfg(feature = "alloc")] 106855e09eSopenharmony_ciuse crate::lib::std::vec::Vec; 116855e09eSopenharmony_ciuse crate::traits::{InputLength, InputTake, ToUsize}; 126855e09eSopenharmony_ciuse core::num::NonZeroUsize; 136855e09eSopenharmony_ci 146855e09eSopenharmony_ci/// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`. 156855e09eSopenharmony_ci/// 166855e09eSopenharmony_ci/// Pre-allocating memory is a nice optimization but count fields can't 176855e09eSopenharmony_ci/// always be trusted. We should clamp initial capacities to some reasonable 186855e09eSopenharmony_ci/// amount. This reduces the risk of a bogus count value triggering a panic 196855e09eSopenharmony_ci/// due to an OOM error. 206855e09eSopenharmony_ci/// 216855e09eSopenharmony_ci/// This does not affect correctness. Nom will always read the full number 226855e09eSopenharmony_ci/// of elements regardless of the capacity cap. 236855e09eSopenharmony_ci#[cfg(feature = "alloc")] 246855e09eSopenharmony_ciconst MAX_INITIAL_CAPACITY_BYTES: usize = 65536; 256855e09eSopenharmony_ci 266855e09eSopenharmony_ci/// Repeats the embedded parser, gathering the results in a `Vec`. 276855e09eSopenharmony_ci/// 286855e09eSopenharmony_ci/// This stops on [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see 296855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 306855e09eSopenharmony_ci/// 316855e09eSopenharmony_ci/// # Arguments 326855e09eSopenharmony_ci/// * `f` The parser to apply. 336855e09eSopenharmony_ci/// 346855e09eSopenharmony_ci/// *Note*: if the parser passed in accepts empty inputs (like `alpha0` or `digit0`), `many0` will 356855e09eSopenharmony_ci/// return an error, to prevent going into an infinite loop 366855e09eSopenharmony_ci/// 376855e09eSopenharmony_ci/// ```rust 386855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 396855e09eSopenharmony_ci/// use nom::multi::many0; 406855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 416855e09eSopenharmony_ci/// 426855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 436855e09eSopenharmony_ci/// many0(tag("abc"))(s) 446855e09eSopenharmony_ci/// } 456855e09eSopenharmony_ci/// 466855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 476855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 486855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); 496855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", vec![]))); 506855e09eSopenharmony_ci/// ``` 516855e09eSopenharmony_ci#[cfg(feature = "alloc")] 526855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 536855e09eSopenharmony_cipub fn many0<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 546855e09eSopenharmony_ciwhere 556855e09eSopenharmony_ci I: Clone + InputLength, 566855e09eSopenharmony_ci F: Parser<I, O, E>, 576855e09eSopenharmony_ci E: ParseError<I>, 586855e09eSopenharmony_ci{ 596855e09eSopenharmony_ci move |mut i: I| { 606855e09eSopenharmony_ci let mut acc = crate::lib::std::vec::Vec::with_capacity(4); 616855e09eSopenharmony_ci loop { 626855e09eSopenharmony_ci let len = i.input_len(); 636855e09eSopenharmony_ci match f.parse(i.clone()) { 646855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, acc)), 656855e09eSopenharmony_ci Err(e) => return Err(e), 666855e09eSopenharmony_ci Ok((i1, o)) => { 676855e09eSopenharmony_ci // infinite loop check: the parser must always consume 686855e09eSopenharmony_ci if i1.input_len() == len { 696855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many0))); 706855e09eSopenharmony_ci } 716855e09eSopenharmony_ci 726855e09eSopenharmony_ci i = i1; 736855e09eSopenharmony_ci acc.push(o); 746855e09eSopenharmony_ci } 756855e09eSopenharmony_ci } 766855e09eSopenharmony_ci } 776855e09eSopenharmony_ci } 786855e09eSopenharmony_ci} 796855e09eSopenharmony_ci 806855e09eSopenharmony_ci/// Runs the embedded parser, gathering the results in a `Vec`. 816855e09eSopenharmony_ci/// 826855e09eSopenharmony_ci/// This stops on [`Err::Error`] if there is at least one result, and returns the results that were accumulated. To instead chain an error up, 836855e09eSopenharmony_ci/// see [`cut`][crate::combinator::cut]. 846855e09eSopenharmony_ci/// 856855e09eSopenharmony_ci/// # Arguments 866855e09eSopenharmony_ci/// * `f` The parser to apply. 876855e09eSopenharmony_ci/// 886855e09eSopenharmony_ci/// *Note*: If the parser passed to `many1` accepts empty inputs 896855e09eSopenharmony_ci/// (like `alpha0` or `digit0`), `many1` will return an error, 906855e09eSopenharmony_ci/// to prevent going into an infinite loop. 916855e09eSopenharmony_ci/// 926855e09eSopenharmony_ci/// ```rust 936855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 946855e09eSopenharmony_ci/// use nom::multi::many1; 956855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 966855e09eSopenharmony_ci/// 976855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 986855e09eSopenharmony_ci/// many1(tag("abc"))(s) 996855e09eSopenharmony_ci/// } 1006855e09eSopenharmony_ci/// 1016855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 1026855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 1036855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); 1046855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); 1056855e09eSopenharmony_ci/// ``` 1066855e09eSopenharmony_ci#[cfg(feature = "alloc")] 1076855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 1086855e09eSopenharmony_cipub fn many1<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 1096855e09eSopenharmony_ciwhere 1106855e09eSopenharmony_ci I: Clone + InputLength, 1116855e09eSopenharmony_ci F: Parser<I, O, E>, 1126855e09eSopenharmony_ci E: ParseError<I>, 1136855e09eSopenharmony_ci{ 1146855e09eSopenharmony_ci move |mut i: I| match f.parse(i.clone()) { 1156855e09eSopenharmony_ci Err(Err::Error(err)) => Err(Err::Error(E::append(i, ErrorKind::Many1, err))), 1166855e09eSopenharmony_ci Err(e) => Err(e), 1176855e09eSopenharmony_ci Ok((i1, o)) => { 1186855e09eSopenharmony_ci let mut acc = crate::lib::std::vec::Vec::with_capacity(4); 1196855e09eSopenharmony_ci acc.push(o); 1206855e09eSopenharmony_ci i = i1; 1216855e09eSopenharmony_ci 1226855e09eSopenharmony_ci loop { 1236855e09eSopenharmony_ci let len = i.input_len(); 1246855e09eSopenharmony_ci match f.parse(i.clone()) { 1256855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, acc)), 1266855e09eSopenharmony_ci Err(e) => return Err(e), 1276855e09eSopenharmony_ci Ok((i1, o)) => { 1286855e09eSopenharmony_ci // infinite loop check: the parser must always consume 1296855e09eSopenharmony_ci if i1.input_len() == len { 1306855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))); 1316855e09eSopenharmony_ci } 1326855e09eSopenharmony_ci 1336855e09eSopenharmony_ci i = i1; 1346855e09eSopenharmony_ci acc.push(o); 1356855e09eSopenharmony_ci } 1366855e09eSopenharmony_ci } 1376855e09eSopenharmony_ci } 1386855e09eSopenharmony_ci } 1396855e09eSopenharmony_ci } 1406855e09eSopenharmony_ci} 1416855e09eSopenharmony_ci 1426855e09eSopenharmony_ci/// Applies the parser `f` until the parser `g` produces a result. 1436855e09eSopenharmony_ci/// 1446855e09eSopenharmony_ci/// Returns a tuple of the results of `f` in a `Vec` and the result of `g`. 1456855e09eSopenharmony_ci/// 1466855e09eSopenharmony_ci/// `f` keeps going so long as `g` produces [`Err::Error`]. To instead chain an error up, see [`cut`][crate::combinator::cut]. 1476855e09eSopenharmony_ci/// 1486855e09eSopenharmony_ci/// ```rust 1496855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 1506855e09eSopenharmony_ci/// use nom::multi::many_till; 1516855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 1526855e09eSopenharmony_ci/// 1536855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, (Vec<&str>, &str)> { 1546855e09eSopenharmony_ci/// many_till(tag("abc"), tag("end"))(s) 1556855e09eSopenharmony_ci/// }; 1566855e09eSopenharmony_ci/// 1576855e09eSopenharmony_ci/// assert_eq!(parser("abcabcend"), Ok(("", (vec!["abc", "abc"], "end")))); 1586855e09eSopenharmony_ci/// assert_eq!(parser("abc123end"), Err(Err::Error(Error::new("123end", ErrorKind::Tag)))); 1596855e09eSopenharmony_ci/// assert_eq!(parser("123123end"), Err(Err::Error(Error::new("123123end", ErrorKind::Tag)))); 1606855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); 1616855e09eSopenharmony_ci/// assert_eq!(parser("abcendefg"), Ok(("efg", (vec!["abc"], "end")))); 1626855e09eSopenharmony_ci/// ``` 1636855e09eSopenharmony_ci#[cfg(feature = "alloc")] 1646855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 1656855e09eSopenharmony_cipub fn many_till<I, O, P, E, F, G>( 1666855e09eSopenharmony_ci mut f: F, 1676855e09eSopenharmony_ci mut g: G, 1686855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, (Vec<O>, P), E> 1696855e09eSopenharmony_ciwhere 1706855e09eSopenharmony_ci I: Clone + InputLength, 1716855e09eSopenharmony_ci F: Parser<I, O, E>, 1726855e09eSopenharmony_ci G: Parser<I, P, E>, 1736855e09eSopenharmony_ci E: ParseError<I>, 1746855e09eSopenharmony_ci{ 1756855e09eSopenharmony_ci move |mut i: I| { 1766855e09eSopenharmony_ci let mut res = crate::lib::std::vec::Vec::new(); 1776855e09eSopenharmony_ci loop { 1786855e09eSopenharmony_ci let len = i.input_len(); 1796855e09eSopenharmony_ci match g.parse(i.clone()) { 1806855e09eSopenharmony_ci Ok((i1, o)) => return Ok((i1, (res, o))), 1816855e09eSopenharmony_ci Err(Err::Error(_)) => { 1826855e09eSopenharmony_ci match f.parse(i.clone()) { 1836855e09eSopenharmony_ci Err(Err::Error(err)) => return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))), 1846855e09eSopenharmony_ci Err(e) => return Err(e), 1856855e09eSopenharmony_ci Ok((i1, o)) => { 1866855e09eSopenharmony_ci // infinite loop check: the parser must always consume 1876855e09eSopenharmony_ci if i1.input_len() == len { 1886855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i1, ErrorKind::ManyTill))); 1896855e09eSopenharmony_ci } 1906855e09eSopenharmony_ci 1916855e09eSopenharmony_ci res.push(o); 1926855e09eSopenharmony_ci i = i1; 1936855e09eSopenharmony_ci } 1946855e09eSopenharmony_ci } 1956855e09eSopenharmony_ci } 1966855e09eSopenharmony_ci Err(e) => return Err(e), 1976855e09eSopenharmony_ci } 1986855e09eSopenharmony_ci } 1996855e09eSopenharmony_ci } 2006855e09eSopenharmony_ci} 2016855e09eSopenharmony_ci 2026855e09eSopenharmony_ci/// Alternates between two parsers to produce a list of elements. 2036855e09eSopenharmony_ci/// 2046855e09eSopenharmony_ci/// This stops when either parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see 2056855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 2066855e09eSopenharmony_ci/// 2076855e09eSopenharmony_ci/// # Arguments 2086855e09eSopenharmony_ci/// * `sep` Parses the separator between list elements. 2096855e09eSopenharmony_ci/// * `f` Parses the elements of the list. 2106855e09eSopenharmony_ci/// 2116855e09eSopenharmony_ci/// ```rust 2126855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 2136855e09eSopenharmony_ci/// use nom::multi::separated_list0; 2146855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 2156855e09eSopenharmony_ci/// 2166855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 2176855e09eSopenharmony_ci/// separated_list0(tag("|"), tag("abc"))(s) 2186855e09eSopenharmony_ci/// } 2196855e09eSopenharmony_ci/// 2206855e09eSopenharmony_ci/// assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"]))); 2216855e09eSopenharmony_ci/// assert_eq!(parser("abc123abc"), Ok(("123abc", vec!["abc"]))); 2226855e09eSopenharmony_ci/// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); 2236855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", vec![]))); 2246855e09eSopenharmony_ci/// assert_eq!(parser("def|abc"), Ok(("def|abc", vec![]))); 2256855e09eSopenharmony_ci/// ``` 2266855e09eSopenharmony_ci#[cfg(feature = "alloc")] 2276855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 2286855e09eSopenharmony_cipub fn separated_list0<I, O, O2, E, F, G>( 2296855e09eSopenharmony_ci mut sep: G, 2306855e09eSopenharmony_ci mut f: F, 2316855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 2326855e09eSopenharmony_ciwhere 2336855e09eSopenharmony_ci I: Clone + InputLength, 2346855e09eSopenharmony_ci F: Parser<I, O, E>, 2356855e09eSopenharmony_ci G: Parser<I, O2, E>, 2366855e09eSopenharmony_ci E: ParseError<I>, 2376855e09eSopenharmony_ci{ 2386855e09eSopenharmony_ci move |mut i: I| { 2396855e09eSopenharmony_ci let mut res = Vec::new(); 2406855e09eSopenharmony_ci 2416855e09eSopenharmony_ci match f.parse(i.clone()) { 2426855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, res)), 2436855e09eSopenharmony_ci Err(e) => return Err(e), 2446855e09eSopenharmony_ci Ok((i1, o)) => { 2456855e09eSopenharmony_ci res.push(o); 2466855e09eSopenharmony_ci i = i1; 2476855e09eSopenharmony_ci } 2486855e09eSopenharmony_ci } 2496855e09eSopenharmony_ci 2506855e09eSopenharmony_ci loop { 2516855e09eSopenharmony_ci let len = i.input_len(); 2526855e09eSopenharmony_ci match sep.parse(i.clone()) { 2536855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, res)), 2546855e09eSopenharmony_ci Err(e) => return Err(e), 2556855e09eSopenharmony_ci Ok((i1, _)) => { 2566855e09eSopenharmony_ci // infinite loop check: the parser must always consume 2576855e09eSopenharmony_ci if i1.input_len() == len { 2586855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); 2596855e09eSopenharmony_ci } 2606855e09eSopenharmony_ci 2616855e09eSopenharmony_ci match f.parse(i1.clone()) { 2626855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, res)), 2636855e09eSopenharmony_ci Err(e) => return Err(e), 2646855e09eSopenharmony_ci Ok((i2, o)) => { 2656855e09eSopenharmony_ci res.push(o); 2666855e09eSopenharmony_ci i = i2; 2676855e09eSopenharmony_ci } 2686855e09eSopenharmony_ci } 2696855e09eSopenharmony_ci } 2706855e09eSopenharmony_ci } 2716855e09eSopenharmony_ci } 2726855e09eSopenharmony_ci } 2736855e09eSopenharmony_ci} 2746855e09eSopenharmony_ci 2756855e09eSopenharmony_ci/// Alternates between two parsers to produce a list of elements until [`Err::Error`]. 2766855e09eSopenharmony_ci/// 2776855e09eSopenharmony_ci/// Fails if the element parser does not produce at least one element.$ 2786855e09eSopenharmony_ci/// 2796855e09eSopenharmony_ci/// This stops when either parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see 2806855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 2816855e09eSopenharmony_ci/// 2826855e09eSopenharmony_ci/// # Arguments 2836855e09eSopenharmony_ci/// * `sep` Parses the separator between list elements. 2846855e09eSopenharmony_ci/// * `f` Parses the elements of the list. 2856855e09eSopenharmony_ci/// ```rust 2866855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 2876855e09eSopenharmony_ci/// use nom::multi::separated_list1; 2886855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 2896855e09eSopenharmony_ci/// 2906855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 2916855e09eSopenharmony_ci/// separated_list1(tag("|"), tag("abc"))(s) 2926855e09eSopenharmony_ci/// } 2936855e09eSopenharmony_ci/// 2946855e09eSopenharmony_ci/// assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"]))); 2956855e09eSopenharmony_ci/// assert_eq!(parser("abc123abc"), Ok(("123abc", vec!["abc"]))); 2966855e09eSopenharmony_ci/// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); 2976855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); 2986855e09eSopenharmony_ci/// assert_eq!(parser("def|abc"), Err(Err::Error(Error::new("def|abc", ErrorKind::Tag)))); 2996855e09eSopenharmony_ci/// ``` 3006855e09eSopenharmony_ci#[cfg(feature = "alloc")] 3016855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 3026855e09eSopenharmony_cipub fn separated_list1<I, O, O2, E, F, G>( 3036855e09eSopenharmony_ci mut sep: G, 3046855e09eSopenharmony_ci mut f: F, 3056855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 3066855e09eSopenharmony_ciwhere 3076855e09eSopenharmony_ci I: Clone + InputLength, 3086855e09eSopenharmony_ci F: Parser<I, O, E>, 3096855e09eSopenharmony_ci G: Parser<I, O2, E>, 3106855e09eSopenharmony_ci E: ParseError<I>, 3116855e09eSopenharmony_ci{ 3126855e09eSopenharmony_ci move |mut i: I| { 3136855e09eSopenharmony_ci let mut res = Vec::new(); 3146855e09eSopenharmony_ci 3156855e09eSopenharmony_ci // Parse the first element 3166855e09eSopenharmony_ci match f.parse(i.clone()) { 3176855e09eSopenharmony_ci Err(e) => return Err(e), 3186855e09eSopenharmony_ci Ok((i1, o)) => { 3196855e09eSopenharmony_ci res.push(o); 3206855e09eSopenharmony_ci i = i1; 3216855e09eSopenharmony_ci } 3226855e09eSopenharmony_ci } 3236855e09eSopenharmony_ci 3246855e09eSopenharmony_ci loop { 3256855e09eSopenharmony_ci let len = i.input_len(); 3266855e09eSopenharmony_ci match sep.parse(i.clone()) { 3276855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, res)), 3286855e09eSopenharmony_ci Err(e) => return Err(e), 3296855e09eSopenharmony_ci Ok((i1, _)) => { 3306855e09eSopenharmony_ci // infinite loop check: the parser must always consume 3316855e09eSopenharmony_ci if i1.input_len() == len { 3326855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); 3336855e09eSopenharmony_ci } 3346855e09eSopenharmony_ci 3356855e09eSopenharmony_ci match f.parse(i1.clone()) { 3366855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((i, res)), 3376855e09eSopenharmony_ci Err(e) => return Err(e), 3386855e09eSopenharmony_ci Ok((i2, o)) => { 3396855e09eSopenharmony_ci res.push(o); 3406855e09eSopenharmony_ci i = i2; 3416855e09eSopenharmony_ci } 3426855e09eSopenharmony_ci } 3436855e09eSopenharmony_ci } 3446855e09eSopenharmony_ci } 3456855e09eSopenharmony_ci } 3466855e09eSopenharmony_ci } 3476855e09eSopenharmony_ci} 3486855e09eSopenharmony_ci 3496855e09eSopenharmony_ci/// Repeats the embedded parser `m..=n` times 3506855e09eSopenharmony_ci/// 3516855e09eSopenharmony_ci/// This stops before `n` when the parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see 3526855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 3536855e09eSopenharmony_ci/// 3546855e09eSopenharmony_ci/// # Arguments 3556855e09eSopenharmony_ci/// * `m` The minimum number of iterations. 3566855e09eSopenharmony_ci/// * `n` The maximum number of iterations. 3576855e09eSopenharmony_ci/// * `f` The parser to apply. 3586855e09eSopenharmony_ci/// 3596855e09eSopenharmony_ci/// *Note*: If the parser passed to `many1` accepts empty inputs 3606855e09eSopenharmony_ci/// (like `alpha0` or `digit0`), `many1` will return an error, 3616855e09eSopenharmony_ci/// to prevent going into an infinite loop. 3626855e09eSopenharmony_ci/// 3636855e09eSopenharmony_ci/// ```rust 3646855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 3656855e09eSopenharmony_ci/// use nom::multi::many_m_n; 3666855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 3676855e09eSopenharmony_ci/// 3686855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 3696855e09eSopenharmony_ci/// many_m_n(0, 2, tag("abc"))(s) 3706855e09eSopenharmony_ci/// } 3716855e09eSopenharmony_ci/// 3726855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 3736855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 3746855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); 3756855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", vec![]))); 3766855e09eSopenharmony_ci/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); 3776855e09eSopenharmony_ci/// ``` 3786855e09eSopenharmony_ci#[cfg(feature = "alloc")] 3796855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 3806855e09eSopenharmony_cipub fn many_m_n<I, O, E, F>( 3816855e09eSopenharmony_ci min: usize, 3826855e09eSopenharmony_ci max: usize, 3836855e09eSopenharmony_ci mut parse: F, 3846855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 3856855e09eSopenharmony_ciwhere 3866855e09eSopenharmony_ci I: Clone + InputLength, 3876855e09eSopenharmony_ci F: Parser<I, O, E>, 3886855e09eSopenharmony_ci E: ParseError<I>, 3896855e09eSopenharmony_ci{ 3906855e09eSopenharmony_ci move |mut input: I| { 3916855e09eSopenharmony_ci if min > max { 3926855e09eSopenharmony_ci return Err(Err::Failure(E::from_error_kind(input, ErrorKind::ManyMN))); 3936855e09eSopenharmony_ci } 3946855e09eSopenharmony_ci 3956855e09eSopenharmony_ci let max_initial_capacity = 3966855e09eSopenharmony_ci MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<O>().max(1); 3976855e09eSopenharmony_ci let mut res = crate::lib::std::vec::Vec::with_capacity(min.min(max_initial_capacity)); 3986855e09eSopenharmony_ci for count in 0..max { 3996855e09eSopenharmony_ci let len = input.input_len(); 4006855e09eSopenharmony_ci match parse.parse(input.clone()) { 4016855e09eSopenharmony_ci Ok((tail, value)) => { 4026855e09eSopenharmony_ci // infinite loop check: the parser must always consume 4036855e09eSopenharmony_ci if tail.input_len() == len { 4046855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(input, ErrorKind::ManyMN))); 4056855e09eSopenharmony_ci } 4066855e09eSopenharmony_ci 4076855e09eSopenharmony_ci res.push(value); 4086855e09eSopenharmony_ci input = tail; 4096855e09eSopenharmony_ci } 4106855e09eSopenharmony_ci Err(Err::Error(e)) => { 4116855e09eSopenharmony_ci if count < min { 4126855e09eSopenharmony_ci return Err(Err::Error(E::append(input, ErrorKind::ManyMN, e))); 4136855e09eSopenharmony_ci } else { 4146855e09eSopenharmony_ci return Ok((input, res)); 4156855e09eSopenharmony_ci } 4166855e09eSopenharmony_ci } 4176855e09eSopenharmony_ci Err(e) => { 4186855e09eSopenharmony_ci return Err(e); 4196855e09eSopenharmony_ci } 4206855e09eSopenharmony_ci } 4216855e09eSopenharmony_ci } 4226855e09eSopenharmony_ci 4236855e09eSopenharmony_ci Ok((input, res)) 4246855e09eSopenharmony_ci } 4256855e09eSopenharmony_ci} 4266855e09eSopenharmony_ci 4276855e09eSopenharmony_ci/// Repeats the embedded parser, counting the results 4286855e09eSopenharmony_ci/// 4296855e09eSopenharmony_ci/// This stops on [`Err::Error`]. To instead chain an error up, see 4306855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 4316855e09eSopenharmony_ci/// 4326855e09eSopenharmony_ci/// # Arguments 4336855e09eSopenharmony_ci/// * `f` The parser to apply. 4346855e09eSopenharmony_ci/// 4356855e09eSopenharmony_ci/// *Note*: if the parser passed in accepts empty inputs (like `alpha0` or `digit0`), `many0` will 4366855e09eSopenharmony_ci/// return an error, to prevent going into an infinite loop 4376855e09eSopenharmony_ci/// 4386855e09eSopenharmony_ci/// ```rust 4396855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 4406855e09eSopenharmony_ci/// use nom::multi::many0_count; 4416855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 4426855e09eSopenharmony_ci/// 4436855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, usize> { 4446855e09eSopenharmony_ci/// many0_count(tag("abc"))(s) 4456855e09eSopenharmony_ci/// } 4466855e09eSopenharmony_ci/// 4476855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", 2))); 4486855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", 1))); 4496855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Ok(("123123", 0))); 4506855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", 0))); 4516855e09eSopenharmony_ci/// ``` 4526855e09eSopenharmony_cipub fn many0_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E> 4536855e09eSopenharmony_ciwhere 4546855e09eSopenharmony_ci I: Clone + InputLength, 4556855e09eSopenharmony_ci F: Parser<I, O, E>, 4566855e09eSopenharmony_ci E: ParseError<I>, 4576855e09eSopenharmony_ci{ 4586855e09eSopenharmony_ci move |i: I| { 4596855e09eSopenharmony_ci let mut input = i; 4606855e09eSopenharmony_ci let mut count = 0; 4616855e09eSopenharmony_ci 4626855e09eSopenharmony_ci loop { 4636855e09eSopenharmony_ci let input_ = input.clone(); 4646855e09eSopenharmony_ci let len = input.input_len(); 4656855e09eSopenharmony_ci match f.parse(input_) { 4666855e09eSopenharmony_ci Ok((i, _)) => { 4676855e09eSopenharmony_ci // infinite loop check: the parser must always consume 4686855e09eSopenharmony_ci if i.input_len() == len { 4696855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0Count))); 4706855e09eSopenharmony_ci } 4716855e09eSopenharmony_ci 4726855e09eSopenharmony_ci input = i; 4736855e09eSopenharmony_ci count += 1; 4746855e09eSopenharmony_ci } 4756855e09eSopenharmony_ci 4766855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((input, count)), 4776855e09eSopenharmony_ci 4786855e09eSopenharmony_ci Err(e) => return Err(e), 4796855e09eSopenharmony_ci } 4806855e09eSopenharmony_ci } 4816855e09eSopenharmony_ci } 4826855e09eSopenharmony_ci} 4836855e09eSopenharmony_ci 4846855e09eSopenharmony_ci/// Runs the embedded parser, counting the results. 4856855e09eSopenharmony_ci/// 4866855e09eSopenharmony_ci/// This stops on [`Err::Error`] if there is at least one result. To instead chain an error up, 4876855e09eSopenharmony_ci/// see [`cut`][crate::combinator::cut]. 4886855e09eSopenharmony_ci/// 4896855e09eSopenharmony_ci/// # Arguments 4906855e09eSopenharmony_ci/// * `f` The parser to apply. 4916855e09eSopenharmony_ci/// 4926855e09eSopenharmony_ci/// *Note*: If the parser passed to `many1` accepts empty inputs 4936855e09eSopenharmony_ci/// (like `alpha0` or `digit0`), `many1` will return an error, 4946855e09eSopenharmony_ci/// to prevent going into an infinite loop. 4956855e09eSopenharmony_ci/// 4966855e09eSopenharmony_ci/// ```rust 4976855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 4986855e09eSopenharmony_ci/// use nom::multi::many1_count; 4996855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 5006855e09eSopenharmony_ci/// 5016855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, usize> { 5026855e09eSopenharmony_ci/// many1_count(tag("abc"))(s) 5036855e09eSopenharmony_ci/// } 5046855e09eSopenharmony_ci/// 5056855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", 2))); 5066855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", 1))); 5076855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Many1Count)))); 5086855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Many1Count)))); 5096855e09eSopenharmony_ci/// ``` 5106855e09eSopenharmony_cipub fn many1_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E> 5116855e09eSopenharmony_ciwhere 5126855e09eSopenharmony_ci I: Clone + InputLength, 5136855e09eSopenharmony_ci F: Parser<I, O, E>, 5146855e09eSopenharmony_ci E: ParseError<I>, 5156855e09eSopenharmony_ci{ 5166855e09eSopenharmony_ci move |i: I| { 5176855e09eSopenharmony_ci let i_ = i.clone(); 5186855e09eSopenharmony_ci match f.parse(i_) { 5196855e09eSopenharmony_ci Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))), 5206855e09eSopenharmony_ci Err(i) => Err(i), 5216855e09eSopenharmony_ci Ok((i1, _)) => { 5226855e09eSopenharmony_ci let mut count = 1; 5236855e09eSopenharmony_ci let mut input = i1; 5246855e09eSopenharmony_ci 5256855e09eSopenharmony_ci loop { 5266855e09eSopenharmony_ci let len = input.input_len(); 5276855e09eSopenharmony_ci let input_ = input.clone(); 5286855e09eSopenharmony_ci match f.parse(input_) { 5296855e09eSopenharmony_ci Err(Err::Error(_)) => return Ok((input, count)), 5306855e09eSopenharmony_ci Err(e) => return Err(e), 5316855e09eSopenharmony_ci Ok((i, _)) => { 5326855e09eSopenharmony_ci // infinite loop check: the parser must always consume 5336855e09eSopenharmony_ci if i.input_len() == len { 5346855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))); 5356855e09eSopenharmony_ci } 5366855e09eSopenharmony_ci 5376855e09eSopenharmony_ci count += 1; 5386855e09eSopenharmony_ci input = i; 5396855e09eSopenharmony_ci } 5406855e09eSopenharmony_ci } 5416855e09eSopenharmony_ci } 5426855e09eSopenharmony_ci } 5436855e09eSopenharmony_ci } 5446855e09eSopenharmony_ci } 5456855e09eSopenharmony_ci} 5466855e09eSopenharmony_ci 5476855e09eSopenharmony_ci/// Runs the embedded parser `count` times, gathering the results in a `Vec` 5486855e09eSopenharmony_ci/// 5496855e09eSopenharmony_ci/// # Arguments 5506855e09eSopenharmony_ci/// * `f` The parser to apply. 5516855e09eSopenharmony_ci/// * `count` How often to apply the parser. 5526855e09eSopenharmony_ci/// ```rust 5536855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 5546855e09eSopenharmony_ci/// use nom::multi::count; 5556855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 5566855e09eSopenharmony_ci/// 5576855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 5586855e09eSopenharmony_ci/// count(tag("abc"), 2)(s) 5596855e09eSopenharmony_ci/// } 5606855e09eSopenharmony_ci/// 5616855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 5626855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Err(Err::Error(Error::new("123", ErrorKind::Tag)))); 5636855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); 5646855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); 5656855e09eSopenharmony_ci/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); 5666855e09eSopenharmony_ci/// ``` 5676855e09eSopenharmony_ci#[cfg(feature = "alloc")] 5686855e09eSopenharmony_ci#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] 5696855e09eSopenharmony_cipub fn count<I, O, E, F>(mut f: F, count: usize) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 5706855e09eSopenharmony_ciwhere 5716855e09eSopenharmony_ci I: Clone + PartialEq, 5726855e09eSopenharmony_ci F: Parser<I, O, E>, 5736855e09eSopenharmony_ci E: ParseError<I>, 5746855e09eSopenharmony_ci{ 5756855e09eSopenharmony_ci move |i: I| { 5766855e09eSopenharmony_ci let mut input = i.clone(); 5776855e09eSopenharmony_ci let max_initial_capacity = 5786855e09eSopenharmony_ci MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<O>().max(1); 5796855e09eSopenharmony_ci let mut res = crate::lib::std::vec::Vec::with_capacity(count.min(max_initial_capacity)); 5806855e09eSopenharmony_ci 5816855e09eSopenharmony_ci for _ in 0..count { 5826855e09eSopenharmony_ci let input_ = input.clone(); 5836855e09eSopenharmony_ci match f.parse(input_) { 5846855e09eSopenharmony_ci Ok((i, o)) => { 5856855e09eSopenharmony_ci res.push(o); 5866855e09eSopenharmony_ci input = i; 5876855e09eSopenharmony_ci } 5886855e09eSopenharmony_ci Err(Err::Error(e)) => { 5896855e09eSopenharmony_ci return Err(Err::Error(E::append(i, ErrorKind::Count, e))); 5906855e09eSopenharmony_ci } 5916855e09eSopenharmony_ci Err(e) => { 5926855e09eSopenharmony_ci return Err(e); 5936855e09eSopenharmony_ci } 5946855e09eSopenharmony_ci } 5956855e09eSopenharmony_ci } 5966855e09eSopenharmony_ci 5976855e09eSopenharmony_ci Ok((input, res)) 5986855e09eSopenharmony_ci } 5996855e09eSopenharmony_ci} 6006855e09eSopenharmony_ci 6016855e09eSopenharmony_ci/// Runs the embedded parser repeatedly, filling the given slice with results. 6026855e09eSopenharmony_ci/// 6036855e09eSopenharmony_ci/// This parser fails if the input runs out before the given slice is full. 6046855e09eSopenharmony_ci/// 6056855e09eSopenharmony_ci/// # Arguments 6066855e09eSopenharmony_ci/// * `f` The parser to apply. 6076855e09eSopenharmony_ci/// * `buf` The slice to fill 6086855e09eSopenharmony_ci/// ```rust 6096855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 6106855e09eSopenharmony_ci/// use nom::multi::fill; 6116855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 6126855e09eSopenharmony_ci/// 6136855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, [&str; 2]> { 6146855e09eSopenharmony_ci/// let mut buf = ["", ""]; 6156855e09eSopenharmony_ci/// let (rest, ()) = fill(tag("abc"), &mut buf)(s)?; 6166855e09eSopenharmony_ci/// Ok((rest, buf)) 6176855e09eSopenharmony_ci/// } 6186855e09eSopenharmony_ci/// 6196855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", ["abc", "abc"]))); 6206855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Err(Err::Error(Error::new("123", ErrorKind::Tag)))); 6216855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); 6226855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); 6236855e09eSopenharmony_ci/// assert_eq!(parser("abcabcabc"), Ok(("abc", ["abc", "abc"]))); 6246855e09eSopenharmony_ci/// ``` 6256855e09eSopenharmony_cipub fn fill<'a, I, O, E, F>(f: F, buf: &'a mut [O]) -> impl FnMut(I) -> IResult<I, (), E> + 'a 6266855e09eSopenharmony_ciwhere 6276855e09eSopenharmony_ci I: Clone + PartialEq, 6286855e09eSopenharmony_ci F: Fn(I) -> IResult<I, O, E> + 'a, 6296855e09eSopenharmony_ci E: ParseError<I>, 6306855e09eSopenharmony_ci{ 6316855e09eSopenharmony_ci move |i: I| { 6326855e09eSopenharmony_ci let mut input = i.clone(); 6336855e09eSopenharmony_ci 6346855e09eSopenharmony_ci for elem in buf.iter_mut() { 6356855e09eSopenharmony_ci let input_ = input.clone(); 6366855e09eSopenharmony_ci match f(input_) { 6376855e09eSopenharmony_ci Ok((i, o)) => { 6386855e09eSopenharmony_ci *elem = o; 6396855e09eSopenharmony_ci input = i; 6406855e09eSopenharmony_ci } 6416855e09eSopenharmony_ci Err(Err::Error(e)) => { 6426855e09eSopenharmony_ci return Err(Err::Error(E::append(i, ErrorKind::Count, e))); 6436855e09eSopenharmony_ci } 6446855e09eSopenharmony_ci Err(e) => { 6456855e09eSopenharmony_ci return Err(e); 6466855e09eSopenharmony_ci } 6476855e09eSopenharmony_ci } 6486855e09eSopenharmony_ci } 6496855e09eSopenharmony_ci 6506855e09eSopenharmony_ci Ok((input, ())) 6516855e09eSopenharmony_ci } 6526855e09eSopenharmony_ci} 6536855e09eSopenharmony_ci 6546855e09eSopenharmony_ci/// Repeats the embedded parser, calling `g` to gather the results. 6556855e09eSopenharmony_ci/// 6566855e09eSopenharmony_ci/// This stops on [`Err::Error`]. To instead chain an error up, see 6576855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 6586855e09eSopenharmony_ci/// 6596855e09eSopenharmony_ci/// # Arguments 6606855e09eSopenharmony_ci/// * `f` The parser to apply. 6616855e09eSopenharmony_ci/// * `init` A function returning the initial value. 6626855e09eSopenharmony_ci/// * `g` The function that combines a result of `f` with 6636855e09eSopenharmony_ci/// the current accumulator. 6646855e09eSopenharmony_ci/// 6656855e09eSopenharmony_ci/// *Note*: if the parser passed in accepts empty inputs (like `alpha0` or `digit0`), `many0` will 6666855e09eSopenharmony_ci/// return an error, to prevent going into an infinite loop 6676855e09eSopenharmony_ci/// 6686855e09eSopenharmony_ci/// ```rust 6696855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 6706855e09eSopenharmony_ci/// use nom::multi::fold_many0; 6716855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 6726855e09eSopenharmony_ci/// 6736855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 6746855e09eSopenharmony_ci/// fold_many0( 6756855e09eSopenharmony_ci/// tag("abc"), 6766855e09eSopenharmony_ci/// Vec::new, 6776855e09eSopenharmony_ci/// |mut acc: Vec<_>, item| { 6786855e09eSopenharmony_ci/// acc.push(item); 6796855e09eSopenharmony_ci/// acc 6806855e09eSopenharmony_ci/// } 6816855e09eSopenharmony_ci/// )(s) 6826855e09eSopenharmony_ci/// } 6836855e09eSopenharmony_ci/// 6846855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 6856855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 6866855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); 6876855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", vec![]))); 6886855e09eSopenharmony_ci/// ``` 6896855e09eSopenharmony_cipub fn fold_many0<I, O, E, F, G, H, R>( 6906855e09eSopenharmony_ci mut f: F, 6916855e09eSopenharmony_ci mut init: H, 6926855e09eSopenharmony_ci mut g: G, 6936855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, R, E> 6946855e09eSopenharmony_ciwhere 6956855e09eSopenharmony_ci I: Clone + InputLength, 6966855e09eSopenharmony_ci F: Parser<I, O, E>, 6976855e09eSopenharmony_ci G: FnMut(R, O) -> R, 6986855e09eSopenharmony_ci H: FnMut() -> R, 6996855e09eSopenharmony_ci E: ParseError<I>, 7006855e09eSopenharmony_ci{ 7016855e09eSopenharmony_ci move |i: I| { 7026855e09eSopenharmony_ci let mut res = init(); 7036855e09eSopenharmony_ci let mut input = i; 7046855e09eSopenharmony_ci 7056855e09eSopenharmony_ci loop { 7066855e09eSopenharmony_ci let i_ = input.clone(); 7076855e09eSopenharmony_ci let len = input.input_len(); 7086855e09eSopenharmony_ci match f.parse(i_) { 7096855e09eSopenharmony_ci Ok((i, o)) => { 7106855e09eSopenharmony_ci // infinite loop check: the parser must always consume 7116855e09eSopenharmony_ci if i.input_len() == len { 7126855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0))); 7136855e09eSopenharmony_ci } 7146855e09eSopenharmony_ci 7156855e09eSopenharmony_ci res = g(res, o); 7166855e09eSopenharmony_ci input = i; 7176855e09eSopenharmony_ci } 7186855e09eSopenharmony_ci Err(Err::Error(_)) => { 7196855e09eSopenharmony_ci return Ok((input, res)); 7206855e09eSopenharmony_ci } 7216855e09eSopenharmony_ci Err(e) => { 7226855e09eSopenharmony_ci return Err(e); 7236855e09eSopenharmony_ci } 7246855e09eSopenharmony_ci } 7256855e09eSopenharmony_ci } 7266855e09eSopenharmony_ci } 7276855e09eSopenharmony_ci} 7286855e09eSopenharmony_ci 7296855e09eSopenharmony_ci/// Repeats the embedded parser, calling `g` to gather the results. 7306855e09eSopenharmony_ci/// 7316855e09eSopenharmony_ci/// This stops on [`Err::Error`] if there is at least one result. To instead chain an error up, 7326855e09eSopenharmony_ci/// see [`cut`][crate::combinator::cut]. 7336855e09eSopenharmony_ci/// 7346855e09eSopenharmony_ci/// # Arguments 7356855e09eSopenharmony_ci/// * `f` The parser to apply. 7366855e09eSopenharmony_ci/// * `init` A function returning the initial value. 7376855e09eSopenharmony_ci/// * `g` The function that combines a result of `f` with 7386855e09eSopenharmony_ci/// the current accumulator. 7396855e09eSopenharmony_ci/// 7406855e09eSopenharmony_ci/// *Note*: If the parser passed to `many1` accepts empty inputs 7416855e09eSopenharmony_ci/// (like `alpha0` or `digit0`), `many1` will return an error, 7426855e09eSopenharmony_ci/// to prevent going into an infinite loop. 7436855e09eSopenharmony_ci/// 7446855e09eSopenharmony_ci/// ```rust 7456855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 7466855e09eSopenharmony_ci/// use nom::multi::fold_many1; 7476855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 7486855e09eSopenharmony_ci/// 7496855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 7506855e09eSopenharmony_ci/// fold_many1( 7516855e09eSopenharmony_ci/// tag("abc"), 7526855e09eSopenharmony_ci/// Vec::new, 7536855e09eSopenharmony_ci/// |mut acc: Vec<_>, item| { 7546855e09eSopenharmony_ci/// acc.push(item); 7556855e09eSopenharmony_ci/// acc 7566855e09eSopenharmony_ci/// } 7576855e09eSopenharmony_ci/// )(s) 7586855e09eSopenharmony_ci/// } 7596855e09eSopenharmony_ci/// 7606855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 7616855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 7626855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Many1)))); 7636855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Many1)))); 7646855e09eSopenharmony_ci/// ``` 7656855e09eSopenharmony_cipub fn fold_many1<I, O, E, F, G, H, R>( 7666855e09eSopenharmony_ci mut f: F, 7676855e09eSopenharmony_ci mut init: H, 7686855e09eSopenharmony_ci mut g: G, 7696855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, R, E> 7706855e09eSopenharmony_ciwhere 7716855e09eSopenharmony_ci I: Clone + InputLength, 7726855e09eSopenharmony_ci F: Parser<I, O, E>, 7736855e09eSopenharmony_ci G: FnMut(R, O) -> R, 7746855e09eSopenharmony_ci H: FnMut() -> R, 7756855e09eSopenharmony_ci E: ParseError<I>, 7766855e09eSopenharmony_ci{ 7776855e09eSopenharmony_ci move |i: I| { 7786855e09eSopenharmony_ci let _i = i.clone(); 7796855e09eSopenharmony_ci let init = init(); 7806855e09eSopenharmony_ci match f.parse(_i) { 7816855e09eSopenharmony_ci Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))), 7826855e09eSopenharmony_ci Err(e) => Err(e), 7836855e09eSopenharmony_ci Ok((i1, o1)) => { 7846855e09eSopenharmony_ci let mut acc = g(init, o1); 7856855e09eSopenharmony_ci let mut input = i1; 7866855e09eSopenharmony_ci 7876855e09eSopenharmony_ci loop { 7886855e09eSopenharmony_ci let _input = input.clone(); 7896855e09eSopenharmony_ci let len = input.input_len(); 7906855e09eSopenharmony_ci match f.parse(_input) { 7916855e09eSopenharmony_ci Err(Err::Error(_)) => { 7926855e09eSopenharmony_ci break; 7936855e09eSopenharmony_ci } 7946855e09eSopenharmony_ci Err(e) => return Err(e), 7956855e09eSopenharmony_ci Ok((i, o)) => { 7966855e09eSopenharmony_ci // infinite loop check: the parser must always consume 7976855e09eSopenharmony_ci if i.input_len() == len { 7986855e09eSopenharmony_ci return Err(Err::Failure(E::from_error_kind(i, ErrorKind::Many1))); 7996855e09eSopenharmony_ci } 8006855e09eSopenharmony_ci 8016855e09eSopenharmony_ci acc = g(acc, o); 8026855e09eSopenharmony_ci input = i; 8036855e09eSopenharmony_ci } 8046855e09eSopenharmony_ci } 8056855e09eSopenharmony_ci } 8066855e09eSopenharmony_ci 8076855e09eSopenharmony_ci Ok((input, acc)) 8086855e09eSopenharmony_ci } 8096855e09eSopenharmony_ci } 8106855e09eSopenharmony_ci } 8116855e09eSopenharmony_ci} 8126855e09eSopenharmony_ci 8136855e09eSopenharmony_ci/// Repeats the embedded parser `m..=n` times, calling `g` to gather the results 8146855e09eSopenharmony_ci/// 8156855e09eSopenharmony_ci/// This stops before `n` when the parser returns [`Err::Error`]. To instead chain an error up, see 8166855e09eSopenharmony_ci/// [`cut`][crate::combinator::cut]. 8176855e09eSopenharmony_ci/// 8186855e09eSopenharmony_ci/// # Arguments 8196855e09eSopenharmony_ci/// * `m` The minimum number of iterations. 8206855e09eSopenharmony_ci/// * `n` The maximum number of iterations. 8216855e09eSopenharmony_ci/// * `f` The parser to apply. 8226855e09eSopenharmony_ci/// * `init` A function returning the initial value. 8236855e09eSopenharmony_ci/// * `g` The function that combines a result of `f` with 8246855e09eSopenharmony_ci/// the current accumulator. 8256855e09eSopenharmony_ci/// 8266855e09eSopenharmony_ci/// *Note*: If the parser passed to `many1` accepts empty inputs 8276855e09eSopenharmony_ci/// (like `alpha0` or `digit0`), `many1` will return an error, 8286855e09eSopenharmony_ci/// to prevent going into an infinite loop. 8296855e09eSopenharmony_ci/// 8306855e09eSopenharmony_ci/// ```rust 8316855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 8326855e09eSopenharmony_ci/// use nom::multi::fold_many_m_n; 8336855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 8346855e09eSopenharmony_ci/// 8356855e09eSopenharmony_ci/// fn parser(s: &str) -> IResult<&str, Vec<&str>> { 8366855e09eSopenharmony_ci/// fold_many_m_n( 8376855e09eSopenharmony_ci/// 0, 8386855e09eSopenharmony_ci/// 2, 8396855e09eSopenharmony_ci/// tag("abc"), 8406855e09eSopenharmony_ci/// Vec::new, 8416855e09eSopenharmony_ci/// |mut acc: Vec<_>, item| { 8426855e09eSopenharmony_ci/// acc.push(item); 8436855e09eSopenharmony_ci/// acc 8446855e09eSopenharmony_ci/// } 8456855e09eSopenharmony_ci/// )(s) 8466855e09eSopenharmony_ci/// } 8476855e09eSopenharmony_ci/// 8486855e09eSopenharmony_ci/// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); 8496855e09eSopenharmony_ci/// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); 8506855e09eSopenharmony_ci/// assert_eq!(parser("123123"), Ok(("123123", vec![]))); 8516855e09eSopenharmony_ci/// assert_eq!(parser(""), Ok(("", vec![]))); 8526855e09eSopenharmony_ci/// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); 8536855e09eSopenharmony_ci/// ``` 8546855e09eSopenharmony_cipub fn fold_many_m_n<I, O, E, F, G, H, R>( 8556855e09eSopenharmony_ci min: usize, 8566855e09eSopenharmony_ci max: usize, 8576855e09eSopenharmony_ci mut parse: F, 8586855e09eSopenharmony_ci mut init: H, 8596855e09eSopenharmony_ci mut fold: G, 8606855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, R, E> 8616855e09eSopenharmony_ciwhere 8626855e09eSopenharmony_ci I: Clone + InputLength, 8636855e09eSopenharmony_ci F: Parser<I, O, E>, 8646855e09eSopenharmony_ci G: FnMut(R, O) -> R, 8656855e09eSopenharmony_ci H: FnMut() -> R, 8666855e09eSopenharmony_ci E: ParseError<I>, 8676855e09eSopenharmony_ci{ 8686855e09eSopenharmony_ci move |mut input: I| { 8696855e09eSopenharmony_ci if min > max { 8706855e09eSopenharmony_ci return Err(Err::Failure(E::from_error_kind(input, ErrorKind::ManyMN))); 8716855e09eSopenharmony_ci } 8726855e09eSopenharmony_ci 8736855e09eSopenharmony_ci let mut acc = init(); 8746855e09eSopenharmony_ci for count in 0..max { 8756855e09eSopenharmony_ci let len = input.input_len(); 8766855e09eSopenharmony_ci match parse.parse(input.clone()) { 8776855e09eSopenharmony_ci Ok((tail, value)) => { 8786855e09eSopenharmony_ci // infinite loop check: the parser must always consume 8796855e09eSopenharmony_ci if tail.input_len() == len { 8806855e09eSopenharmony_ci return Err(Err::Error(E::from_error_kind(tail, ErrorKind::ManyMN))); 8816855e09eSopenharmony_ci } 8826855e09eSopenharmony_ci 8836855e09eSopenharmony_ci acc = fold(acc, value); 8846855e09eSopenharmony_ci input = tail; 8856855e09eSopenharmony_ci } 8866855e09eSopenharmony_ci //FInputXMError: handle failure properly 8876855e09eSopenharmony_ci Err(Err::Error(err)) => { 8886855e09eSopenharmony_ci if count < min { 8896855e09eSopenharmony_ci return Err(Err::Error(E::append(input, ErrorKind::ManyMN, err))); 8906855e09eSopenharmony_ci } else { 8916855e09eSopenharmony_ci break; 8926855e09eSopenharmony_ci } 8936855e09eSopenharmony_ci } 8946855e09eSopenharmony_ci Err(e) => return Err(e), 8956855e09eSopenharmony_ci } 8966855e09eSopenharmony_ci } 8976855e09eSopenharmony_ci 8986855e09eSopenharmony_ci Ok((input, acc)) 8996855e09eSopenharmony_ci } 9006855e09eSopenharmony_ci} 9016855e09eSopenharmony_ci 9026855e09eSopenharmony_ci/// Gets a number from the parser and returns a 9036855e09eSopenharmony_ci/// subslice of the input of that size. 9046855e09eSopenharmony_ci/// If the parser returns `Incomplete`, 9056855e09eSopenharmony_ci/// `length_data` will return an error. 9066855e09eSopenharmony_ci/// # Arguments 9076855e09eSopenharmony_ci/// * `f` The parser to apply. 9086855e09eSopenharmony_ci/// ```rust 9096855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed, IResult}; 9106855e09eSopenharmony_ci/// use nom::number::complete::be_u16; 9116855e09eSopenharmony_ci/// use nom::multi::length_data; 9126855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 9136855e09eSopenharmony_ci/// 9146855e09eSopenharmony_ci/// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { 9156855e09eSopenharmony_ci/// length_data(be_u16)(s) 9166855e09eSopenharmony_ci/// } 9176855e09eSopenharmony_ci/// 9186855e09eSopenharmony_ci/// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); 9196855e09eSopenharmony_ci/// assert_eq!(parser(b"\x00\x03a"), Err(Err::Incomplete(Needed::new(2)))); 9206855e09eSopenharmony_ci/// ``` 9216855e09eSopenharmony_cipub fn length_data<I, N, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, I, E> 9226855e09eSopenharmony_ciwhere 9236855e09eSopenharmony_ci I: InputLength + InputTake, 9246855e09eSopenharmony_ci N: ToUsize, 9256855e09eSopenharmony_ci F: Parser<I, N, E>, 9266855e09eSopenharmony_ci E: ParseError<I>, 9276855e09eSopenharmony_ci{ 9286855e09eSopenharmony_ci move |i: I| { 9296855e09eSopenharmony_ci let (i, length) = f.parse(i)?; 9306855e09eSopenharmony_ci 9316855e09eSopenharmony_ci let length: usize = length.to_usize(); 9326855e09eSopenharmony_ci 9336855e09eSopenharmony_ci if let Some(needed) = length 9346855e09eSopenharmony_ci .checked_sub(i.input_len()) 9356855e09eSopenharmony_ci .and_then(NonZeroUsize::new) 9366855e09eSopenharmony_ci { 9376855e09eSopenharmony_ci Err(Err::Incomplete(Needed::Size(needed))) 9386855e09eSopenharmony_ci } else { 9396855e09eSopenharmony_ci Ok(i.take_split(length)) 9406855e09eSopenharmony_ci } 9416855e09eSopenharmony_ci } 9426855e09eSopenharmony_ci} 9436855e09eSopenharmony_ci 9446855e09eSopenharmony_ci/// Gets a number from the first parser, 9456855e09eSopenharmony_ci/// takes a subslice of the input of that size, 9466855e09eSopenharmony_ci/// then applies the second parser on that subslice. 9476855e09eSopenharmony_ci/// If the second parser returns `Incomplete`, 9486855e09eSopenharmony_ci/// `length_value` will return an error. 9496855e09eSopenharmony_ci/// # Arguments 9506855e09eSopenharmony_ci/// * `f` The parser to apply. 9516855e09eSopenharmony_ci/// * `g` The parser to apply on the subslice. 9526855e09eSopenharmony_ci/// ```rust 9536855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 9546855e09eSopenharmony_ci/// use nom::number::complete::be_u16; 9556855e09eSopenharmony_ci/// use nom::multi::length_value; 9566855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 9576855e09eSopenharmony_ci/// 9586855e09eSopenharmony_ci/// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { 9596855e09eSopenharmony_ci/// length_value(be_u16, tag("abc"))(s) 9606855e09eSopenharmony_ci/// } 9616855e09eSopenharmony_ci/// 9626855e09eSopenharmony_ci/// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); 9636855e09eSopenharmony_ci/// assert_eq!(parser(b"\x00\x03123123"), Err(Err::Error(Error::new(&b"123"[..], ErrorKind::Tag)))); 9646855e09eSopenharmony_ci/// assert_eq!(parser(b"\x00\x03a"), Err(Err::Incomplete(Needed::new(2)))); 9656855e09eSopenharmony_ci/// ``` 9666855e09eSopenharmony_cipub fn length_value<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, O, E> 9676855e09eSopenharmony_ciwhere 9686855e09eSopenharmony_ci I: Clone + InputLength + InputTake, 9696855e09eSopenharmony_ci N: ToUsize, 9706855e09eSopenharmony_ci F: Parser<I, N, E>, 9716855e09eSopenharmony_ci G: Parser<I, O, E>, 9726855e09eSopenharmony_ci E: ParseError<I>, 9736855e09eSopenharmony_ci{ 9746855e09eSopenharmony_ci move |i: I| { 9756855e09eSopenharmony_ci let (i, length) = f.parse(i)?; 9766855e09eSopenharmony_ci 9776855e09eSopenharmony_ci let length: usize = length.to_usize(); 9786855e09eSopenharmony_ci 9796855e09eSopenharmony_ci if let Some(needed) = length 9806855e09eSopenharmony_ci .checked_sub(i.input_len()) 9816855e09eSopenharmony_ci .and_then(NonZeroUsize::new) 9826855e09eSopenharmony_ci { 9836855e09eSopenharmony_ci Err(Err::Incomplete(Needed::Size(needed))) 9846855e09eSopenharmony_ci } else { 9856855e09eSopenharmony_ci let (rest, i) = i.take_split(length); 9866855e09eSopenharmony_ci match g.parse(i.clone()) { 9876855e09eSopenharmony_ci Err(Err::Incomplete(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))), 9886855e09eSopenharmony_ci Err(e) => Err(e), 9896855e09eSopenharmony_ci Ok((_, o)) => Ok((rest, o)), 9906855e09eSopenharmony_ci } 9916855e09eSopenharmony_ci } 9926855e09eSopenharmony_ci } 9936855e09eSopenharmony_ci} 9946855e09eSopenharmony_ci 9956855e09eSopenharmony_ci/// Gets a number from the first parser, 9966855e09eSopenharmony_ci/// then applies the second parser that many times. 9976855e09eSopenharmony_ci/// # Arguments 9986855e09eSopenharmony_ci/// * `f` The parser to apply to obtain the count. 9996855e09eSopenharmony_ci/// * `g` The parser to apply repeatedly. 10006855e09eSopenharmony_ci/// ```rust 10016855e09eSopenharmony_ci/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; 10026855e09eSopenharmony_ci/// use nom::number::complete::u8; 10036855e09eSopenharmony_ci/// use nom::multi::length_count; 10046855e09eSopenharmony_ci/// use nom::bytes::complete::tag; 10056855e09eSopenharmony_ci/// use nom::combinator::map; 10066855e09eSopenharmony_ci/// 10076855e09eSopenharmony_ci/// fn parser(s: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { 10086855e09eSopenharmony_ci/// length_count(map(u8, |i| { 10096855e09eSopenharmony_ci/// println!("got number: {}", i); 10106855e09eSopenharmony_ci/// i 10116855e09eSopenharmony_ci/// }), tag("abc"))(s) 10126855e09eSopenharmony_ci/// } 10136855e09eSopenharmony_ci/// 10146855e09eSopenharmony_ci/// assert_eq!(parser(&b"\x02abcabcabc"[..]), Ok(((&b"abc"[..], vec![&b"abc"[..], &b"abc"[..]])))); 10156855e09eSopenharmony_ci/// assert_eq!(parser(b"\x03123123123"), Err(Err::Error(Error::new(&b"123123123"[..], ErrorKind::Tag)))); 10166855e09eSopenharmony_ci/// ``` 10176855e09eSopenharmony_ci#[cfg(feature = "alloc")] 10186855e09eSopenharmony_cipub fn length_count<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, Vec<O>, E> 10196855e09eSopenharmony_ciwhere 10206855e09eSopenharmony_ci I: Clone, 10216855e09eSopenharmony_ci N: ToUsize, 10226855e09eSopenharmony_ci F: Parser<I, N, E>, 10236855e09eSopenharmony_ci G: Parser<I, O, E>, 10246855e09eSopenharmony_ci E: ParseError<I>, 10256855e09eSopenharmony_ci{ 10266855e09eSopenharmony_ci move |i: I| { 10276855e09eSopenharmony_ci let (i, count) = f.parse(i)?; 10286855e09eSopenharmony_ci let mut input = i.clone(); 10296855e09eSopenharmony_ci let mut res = Vec::new(); 10306855e09eSopenharmony_ci 10316855e09eSopenharmony_ci for _ in 0..count.to_usize() { 10326855e09eSopenharmony_ci let input_ = input.clone(); 10336855e09eSopenharmony_ci match g.parse(input_) { 10346855e09eSopenharmony_ci Ok((i, o)) => { 10356855e09eSopenharmony_ci res.push(o); 10366855e09eSopenharmony_ci input = i; 10376855e09eSopenharmony_ci } 10386855e09eSopenharmony_ci Err(Err::Error(e)) => { 10396855e09eSopenharmony_ci return Err(Err::Error(E::append(i, ErrorKind::Count, e))); 10406855e09eSopenharmony_ci } 10416855e09eSopenharmony_ci Err(e) => { 10426855e09eSopenharmony_ci return Err(e); 10436855e09eSopenharmony_ci } 10446855e09eSopenharmony_ci } 10456855e09eSopenharmony_ci } 10466855e09eSopenharmony_ci 10476855e09eSopenharmony_ci Ok((input, res)) 10486855e09eSopenharmony_ci } 10496855e09eSopenharmony_ci} 1050