//! Combinators applying their child parser multiple times #[macro_use] mod macros; use crate::error::ErrorKind; use crate::error::ParseError; use crate::internal::{Err, IResult, Needed, Parser}; #[cfg(feature = "alloc")] use crate::lib::std::vec::Vec; use crate::traits::{InputLength, InputTake, ToUsize}; use core::num::NonZeroUsize; /// Repeats the embedded parser until it fails /// and returns the results in a `Vec`. /// /// # Arguments /// * `f` The parser to apply. /// /// *Note*: if the parser passed to `many0` accepts empty inputs /// (like `alpha0` or `digit0`), `many0` will return an error, /// to prevent going into an infinite loop /// /// ```rust /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::many0; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// many0(tag("abc"))(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many0(mut f: F) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |mut i: I| { let mut acc = crate::lib::std::vec::Vec::with_capacity(4); loop { match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, acc)), Err(e) => return Err(e), Ok((i1, o)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many0))); } i = i1; acc.push(o); } } } } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many0c(input: I, f: F) -> IResult, E> where I: Clone + PartialEq, F: Fn(I) -> IResult, E: ParseError, { many0(f)(input) } /// Runs the embedded parser until it fails and /// returns the results in a `Vec`. Fails if /// the embedded parser does not produce at least /// one result. /// /// # Arguments /// * `f` The parser to apply. /// /// *Note*: If the parser passed to `many1` accepts empty inputs /// (like `alpha0` or `digit0`), `many1` will return an error, /// to prevent going into an infinite loop. /// /// ```rust /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many1; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// many1(tag("abc"))(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many1(mut f: F) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |mut i: I| match f.parse(i.clone()) { Err(Err::Error(err)) => Err(Err::Error(E::append(i, ErrorKind::Many1, err))), Err(e) => Err(e), Ok((i1, o)) => { let mut acc = crate::lib::std::vec::Vec::with_capacity(4); acc.push(o); i = i1; loop { match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, acc)), Err(e) => return Err(e), Ok((i1, o)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))); } i = i1; acc.push(o); } } } } } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many1c(input: I, f: F) -> IResult, E> where I: Clone + PartialEq, F: Fn(I) -> IResult, E: ParseError, { many1(f)(input) } /// Applies the parser `f` until the parser `g` produces /// a result. Returns a pair consisting of the results of /// `f` in a `Vec` and the result of `g`. /// ```rust /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many_till; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, (Vec<&str>, &str)> { /// many_till(tag("abc"), tag("end"))(s) /// }; /// /// assert_eq!(parser("abcabcend"), Ok(("", (vec!["abc", "abc"], "end")))); /// assert_eq!(parser("abc123end"), Err(Err::Error(Error::new("123end", ErrorKind::Tag)))); /// assert_eq!(parser("123123end"), Err(Err::Error(Error::new("123123end", ErrorKind::Tag)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("abcendefg"), Ok(("efg", (vec!["abc"], "end")))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many_till( mut f: F, mut g: G, ) -> impl FnMut(I) -> IResult, P), E> where I: Clone + PartialEq, F: Parser, G: Parser, E: ParseError, { move |mut i: I| { let mut res = crate::lib::std::vec::Vec::new(); loop { match g.parse(i.clone()) { Ok((i1, o)) => return Ok((i1, (res, o))), Err(Err::Error(_)) => { match f.parse(i.clone()) { Err(Err::Error(err)) => return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))), Err(e) => return Err(e), Ok((i1, o)) => { // loop trip must always consume (otherwise infinite loops) if i1 == i { return Err(Err::Error(E::from_error_kind(i1, ErrorKind::ManyTill))); } res.push(o); i = i1; } } } Err(e) => return Err(e), } } } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many_tillc(i: I, f: F, g: G) -> IResult, P), E> where I: Clone + PartialEq, F: Fn(I) -> IResult, G: Fn(I) -> IResult, E: ParseError, { many_till(f, g)(i) } /// Alternates between two parsers to produce /// a list of elements. /// # Arguments /// * `sep` Parses the separator between list elements. /// * `f` Parses the elements of the list. /// /// ```rust /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::separated_list0; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// separated_list0(tag("|"), tag("abc"))(s) /// } /// /// assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"]))); /// assert_eq!(parser("abc123abc"), Ok(("123abc", vec!["abc"]))); /// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("def|abc"), Ok(("def|abc", vec![]))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn separated_list0( mut sep: G, mut f: F, ) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, G: Parser, E: ParseError, { move |mut i: I| { let mut res = Vec::new(); match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, o)) => { res.push(o); i = i1; } } loop { match sep.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, _)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); } match f.parse(i1.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i2, o)) => { res.push(o); i = i2; } } } } } } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn separated_list0c(i: I, sep: G, f: F) -> IResult, E> where I: Clone + PartialEq, F: Fn(I) -> IResult, G: Fn(I) -> IResult, E: ParseError, { separated_list0(sep, f)(i) } /// Alternates between two parsers to produce /// a list of elements. Fails if the element /// parser does not produce at least one element. /// # Arguments /// * `sep` Parses the separator between list elements. /// * `f` Parses the elements of the list. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::separated_list1; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// separated_list1(tag("|"), tag("abc"))(s) /// } /// /// assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"]))); /// assert_eq!(parser("abc123abc"), Ok(("123abc", vec!["abc"]))); /// assert_eq!(parser("abc|def"), Ok(("|def", vec!["abc"]))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("def|abc"), Err(Err::Error(Error::new("def|abc", ErrorKind::Tag)))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn separated_list1( mut sep: G, mut f: F, ) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, G: Parser, E: ParseError, { move |mut i: I| { let mut res = Vec::new(); // Parse the first element match f.parse(i.clone()) { Err(e) => return Err(e), Ok((i1, o)) => { res.push(o); i = i1; } } loop { match sep.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, _)) => { if i1 == i { return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); } match f.parse(i1.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i2, o)) => { res.push(o); i = i2; } } } } } } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn separated_list1c(i: I, sep: G, f: F) -> IResult, E> where I: Clone + PartialEq, F: Fn(I) -> IResult, G: Fn(I) -> IResult, E: ParseError, { separated_list1(sep, f)(i) } /// Repeats the embedded parser `n` times or until it fails /// and returns the results in a `Vec`. Fails if the /// embedded parser does not succeed at least `m` times. /// # Arguments /// * `m` The minimum number of iterations. /// * `n` The maximum number of iterations. /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::many_m_n; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// many_m_n(0, 2, tag("abc"))(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn many_m_n( min: usize, max: usize, mut parse: F, ) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |mut input: I| { let mut res = crate::lib::std::vec::Vec::with_capacity(min); for count in 0..max { match parse.parse(input.clone()) { Ok((tail, value)) => { // do not allow parsers that do not consume input (causes infinite loops) if tail == input { return Err(Err::Error(E::from_error_kind(input, ErrorKind::ManyMN))); } res.push(value); input = tail; } Err(Err::Error(e)) => { if count < min { return Err(Err::Error(E::append(input, ErrorKind::ManyMN, e))); } else { return Ok((input, res)); } } Err(e) => { return Err(e); } } } Ok((input, res)) } } // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] pub fn many_m_nc(i: I, m: usize, n: usize, f: F) -> IResult, E> where I: Clone + PartialEq, F: Fn(I) -> IResult, E: ParseError, { many_m_n(m, n, f)(i) } /// Repeats the embedded parser until it fails /// and returns the number of successful iterations. /// # Arguments /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::many0_count; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, usize> { /// many0_count(tag("abc"))(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", 2))); /// assert_eq!(parser("abc123"), Ok(("123", 1))); /// assert_eq!(parser("123123"), Ok(("123123", 0))); /// assert_eq!(parser(""), Ok(("", 0))); /// ``` pub fn many0_count(mut f: F) -> impl FnMut(I) -> IResult where I: Clone + PartialEq, F: Parser, E: ParseError, { move |i: I| { let mut input = i; let mut count = 0; loop { let input_ = input.clone(); match f.parse(input_) { Ok((i, _)) => { // loop trip must always consume (otherwise infinite loops) if i == input { return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0Count))); } input = i; count += 1; } Err(Err::Error(_)) => return Ok((input, count)), Err(e) => return Err(e), } } } } #[doc(hidden)] pub fn many0_countc(i: I, f: F) -> IResult where I: Clone + PartialEq, F: Fn(I) -> IResult, E: ParseError, { many0_count(f)(i) } /// Repeats the embedded parser until it fails /// and returns the number of successful iterations. /// Fails if the embedded parser does not succeed /// at least once. /// # Arguments /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many1_count; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, usize> { /// many1_count(tag("abc"))(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", 2))); /// assert_eq!(parser("abc123"), Ok(("123", 1))); /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Many1Count)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Many1Count)))); /// ``` pub fn many1_count(mut f: F) -> impl FnMut(I) -> IResult where I: Clone + PartialEq, F: Parser, E: ParseError, { move |i: I| { let i_ = i.clone(); match f.parse(i_) { Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))), Err(i) => Err(i), Ok((i1, _)) => { let mut count = 1; let mut input = i1; loop { let input_ = input.clone(); match f.parse(input_) { Err(Err::Error(_)) => return Ok((input, count)), Err(e) => return Err(e), Ok((i, _)) => { if i == input { return Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))); } count += 1; input = i; } } } } } } } #[doc(hidden)] pub fn many1_countc(i: I, f: F) -> IResult where I: Clone + PartialEq, F: Fn(I) -> IResult, E: ParseError, { many1_count(f)(i) } /// Runs the embedded parser a specified number /// of times. Returns the results in a `Vec`. /// # Arguments /// * `f` The parser to apply. /// * `count` How often to apply the parser. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::count; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// count(tag("abc"), 2)(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Err(Err::Error(Error::new("123", ErrorKind::Tag)))); /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` #[cfg(feature = "alloc")] #[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] pub fn count(mut f: F, count: usize) -> impl FnMut(I) -> IResult, E> where I: Clone + PartialEq, F: Parser, E: ParseError, { move |i: I| { let mut input = i.clone(); let mut res = crate::lib::std::vec::Vec::with_capacity(count); for _ in 0..count { let input_ = input.clone(); match f.parse(input_) { Ok((i, o)) => { res.push(o); input = i; } Err(Err::Error(e)) => { return Err(Err::Error(E::append(i, ErrorKind::Count, e))); } Err(e) => { return Err(e); } } } Ok((input, res)) } } /// Runs the embedded parser repeatedly, filling the given slice with results. This parser fails if /// the input runs out before the given slice is full. /// # Arguments /// * `f` The parser to apply. /// * `buf` The slice to fill /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::fill; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, [&str; 2]> { /// let mut buf = ["", ""]; /// let (rest, ()) = fill(tag("abc"), &mut buf)(s)?; /// Ok((rest, buf)) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", ["abc", "abc"]))); /// assert_eq!(parser("abc123"), Err(Err::Error(Error::new("123", ErrorKind::Tag)))); /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Tag)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", ["abc", "abc"]))); /// ``` pub fn fill<'a, I, O, E, F>(f: F, buf: &'a mut [O]) -> impl FnMut(I) -> IResult + 'a where I: Clone + PartialEq, F: Fn(I) -> IResult + 'a, E: ParseError, { move |i: I| { let mut input = i.clone(); for elem in buf.iter_mut() { let input_ = input.clone(); match f(input_) { Ok((i, o)) => { *elem = o; input = i; } Err(Err::Error(e)) => { return Err(Err::Error(E::append(i, ErrorKind::Count, e))); } Err(e) => { return Err(e); } } } Ok((input, ())) } } /// Applies a parser until it fails and accumulates /// the results using a given function and initial value. /// # Arguments /// * `f` The parser to apply. /// * `init` The initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::fold_many0; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// fold_many0( /// tag("abc"), /// Vec::new(), /// |mut acc: Vec<_>, item| { /// acc.push(item); /// acc /// } /// )(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// ``` pub fn fold_many0( mut f: F, init: R, mut g: G, ) -> impl FnMut(I) -> IResult where I: Clone + PartialEq, F: Parser, G: FnMut(R, O) -> R, E: ParseError, R: Clone, { move |i: I| { let mut res = init.clone(); let mut input = i; loop { let i_ = input.clone(); match f.parse(i_) { Ok((i, o)) => { // loop trip must always consume (otherwise infinite loops) if i == input { return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0))); } res = g(res, o); input = i; } Err(Err::Error(_)) => { return Ok((input, res)); } Err(e) => { return Err(e); } } } } } #[doc(hidden)] pub fn fold_many0c(i: I, f: F, init: R, g: G) -> IResult where I: Clone + PartialEq, F: Fn(I) -> IResult, G: FnMut(R, O) -> R, E: ParseError, R: Clone, { fold_many0(f, init, g)(i) } /// Applies a parser until it fails and accumulates /// the results using a given function and initial value. /// Fails if the embedded parser does not succeed at least /// once. /// # Arguments /// * `f` The parser to apply. /// * `init` The initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::fold_many1; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// fold_many1( /// tag("abc"), /// Vec::new(), /// |mut acc: Vec<_>, item| { /// acc.push(item); /// acc /// } /// )(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Err(Err::Error(Error::new("123123", ErrorKind::Many1)))); /// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Many1)))); /// ``` pub fn fold_many1( mut f: F, init: R, mut g: G, ) -> impl FnMut(I) -> IResult where I: Clone + PartialEq, F: Parser, G: FnMut(R, O) -> R, E: ParseError, R: Clone, { move |i: I| { let _i = i.clone(); let init = init.clone(); match f.parse(_i) { Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))), Err(e) => Err(e), Ok((i1, o1)) => { let mut acc = g(init, o1); let mut input = i1; loop { let _input = input.clone(); match f.parse(_input) { Err(Err::Error(_)) => { break; } Err(e) => return Err(e), Ok((i, o)) => { if i == input { return Err(Err::Failure(E::from_error_kind(i, ErrorKind::Many1))); } acc = g(acc, o); input = i; } } } Ok((input, acc)) } } } } #[doc(hidden)] pub fn fold_many1c(i: I, f: F, init: R, g: G) -> IResult where I: Clone + PartialEq, F: Fn(I) -> IResult, G: FnMut(R, O) -> R, E: ParseError, R: Clone, { fold_many1(f, init, g)(i) } /// Applies a parser `n` times or until it fails and accumulates /// the results using a given function and initial value. /// Fails if the embedded parser does not succeed at least `m` /// times. /// # Arguments /// * `m` The minimum number of iterations. /// * `n` The maximum number of iterations. /// * `f` The parser to apply. /// * `init` The initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::multi::fold_many_m_n; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { /// fold_many_m_n( /// 0, /// 2, /// tag("abc"), /// Vec::new(), /// |mut acc: Vec<_>, item| { /// acc.push(item); /// acc /// } /// )(s) /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` pub fn fold_many_m_n( min: usize, max: usize, mut parse: F, init: R, mut fold: G, ) -> impl FnMut(I) -> IResult where I: Clone + PartialEq, F: Parser, G: FnMut(R, O) -> R, E: ParseError, R: Clone, { move |mut input: I| { let mut acc = init.clone(); for count in 0..max { match parse.parse(input.clone()) { Ok((tail, value)) => { // do not allow parsers that do not consume input (causes infinite loops) if tail == input { return Err(Err::Error(E::from_error_kind(tail, ErrorKind::ManyMN))); } acc = fold(acc, value); input = tail; } //FInputXMError: handle failure properly Err(Err::Error(err)) => { if count < min { return Err(Err::Error(E::append(input, ErrorKind::ManyMN, err))); } else { break; } } Err(e) => return Err(e), } } Ok((input, acc)) } } #[doc(hidden)] pub fn fold_many_m_nc( input: I, min: usize, max: usize, parse: F, init: R, fold: G, ) -> IResult where I: Clone + PartialEq, F: Fn(I) -> IResult, G: Fn(R, O) -> R, E: ParseError, R: Clone, { fold_many_m_n(min, max, parse, init, fold)(input) } /// Gets a number from the parser and returns a /// subslice of the input of that size. /// If the parser returns `Incomplete`, /// `length_data` will return an error. /// # Arguments /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::ErrorKind, Needed, IResult}; /// use nom::number::complete::be_u16; /// use nom::multi::length_data; /// use nom::bytes::complete::tag; /// /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { /// length_data(be_u16)(s) /// } /// /// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); /// assert_eq!(parser(b"\x00\x03a"), Err(Err::Incomplete(Needed::new(2)))); /// ``` pub fn length_data(mut f: F) -> impl FnMut(I) -> IResult where I: InputLength + InputTake, N: ToUsize, F: Parser, E: ParseError, { move |i: I| { let (i, length) = f.parse(i)?; let length: usize = length.to_usize(); if let Some(needed) = length .checked_sub(i.input_len()) .and_then(NonZeroUsize::new) { Err(Err::Incomplete(Needed::Size(needed))) } else { Ok(i.take_split(length)) } } } /// Gets a number from the first parser, /// takes a subslice of the input of that size, /// then applies the second parser on that subslice. /// If the second parser returns `Incomplete`, /// `length_value` will return an error. /// # Arguments /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::number::complete::be_u16; /// use nom::multi::length_value; /// use nom::bytes::complete::tag; /// /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { /// length_value(be_u16, tag("abc"))(s) /// } /// /// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); /// assert_eq!(parser(b"\x00\x03123123"), Err(Err::Error(Error::new(&b"123"[..], ErrorKind::Tag)))); /// assert_eq!(parser(b"\x00\x03a"), Err(Err::Incomplete(Needed::new(2)))); /// ``` pub fn length_value(mut f: F, mut g: G) -> impl FnMut(I) -> IResult where I: Clone + InputLength + InputTake, N: ToUsize, F: Parser, G: Parser, E: ParseError, { move |i: I| { let (i, length) = f.parse(i)?; let length: usize = length.to_usize(); if let Some(needed) = length .checked_sub(i.input_len()) .and_then(NonZeroUsize::new) { Err(Err::Incomplete(Needed::Size(needed))) } else { let (rest, i) = i.take_split(length); match g.parse(i.clone()) { Err(Err::Incomplete(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))), Err(e) => Err(e), Ok((_, o)) => Ok((rest, o)), } } } } #[doc(hidden)] pub fn length_valuec(i: I, f: F, g: G) -> IResult where I: Clone + InputLength + InputTake, N: ToUsize, F: Fn(I) -> IResult, G: Fn(I) -> IResult, E: ParseError, { length_value(f, g)(i) } /// Gets a number from the first parser, /// then applies the second parser that many times. /// Arguments /// * `f` The parser to apply to obtain the count. /// * `g` The parser to apply repeatedly. /// ```rust /// # #[macro_use] extern crate nom; /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::number::complete::u8; /// use nom::multi::length_count; /// use nom::bytes::complete::tag; /// use nom::combinator::map; /// /// fn parser(s: &[u8]) -> IResult<&[u8], Vec<&[u8]>> { /// length_count(map(u8, |i| { /// println!("got number: {}", i); /// i /// }), tag("abc"))(s) /// } /// /// assert_eq!(parser(&b"\x02abcabcabc"[..]), Ok(((&b"abc"[..], vec![&b"abc"[..], &b"abc"[..]])))); /// assert_eq!(parser(b"\x03123123123"), Err(Err::Error(Error::new(&b"123123123"[..], ErrorKind::Tag)))); /// ``` #[cfg(feature = "alloc")] pub fn length_count(mut f: F, mut g: G) -> impl FnMut(I) -> IResult, E> where I: Clone, N: ToUsize, F: Parser, G: Parser, E: ParseError, { move |i: I| { let (i, count) = f.parse(i)?; let mut input = i.clone(); let mut res = Vec::new(); for _ in 0..count.to_usize() { let input_ = input.clone(); match g.parse(input_) { Ok((i, o)) => { res.push(o); input = i; } Err(Err::Error(e)) => { return Err(Err::Error(E::append(i, ErrorKind::Count, e))); } Err(e) => { return Err(e); } } } Ok((input, res)) } }