diff options
Diffstat (limited to 'src/multi/mod.rs')
-rw-r--r-- | src/multi/mod.rs | 531 |
1 files changed, 328 insertions, 203 deletions
diff --git a/src/multi/mod.rs b/src/multi/mod.rs index e8f26dd..46a59ed 100644 --- a/src/multi/mod.rs +++ b/src/multi/mod.rs @@ -1,14 +1,15 @@ -//! combinators applying their child parser multiple times +//! Combinators applying their child parser multiple times #[macro_use] mod macros; -use crate::internal::{Err, IResult, Needed}; +use crate::error::ErrorKind; use crate::error::ParseError; -use crate::traits::{InputLength, InputTake, ToUsize}; +use crate::internal::{Err, IResult, Needed, Parser}; #[cfg(feature = "alloc")] use crate::lib::std::vec::Vec; -use crate::error::ErrorKind; +use crate::traits::{InputLength, InputTake, ToUsize}; +use core::num::NonZeroUsize; /// Repeats the embedded parser until it fails /// and returns the results in a `Vec`. @@ -35,17 +36,17 @@ use crate::error::ErrorKind; /// assert_eq!(parser(""), Ok(("", vec![]))); /// ``` #[cfg(feature = "alloc")] -pub fn many0<I, O, E, F>(f: F) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn many0<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { - move |i: I| { + move |mut i: I| { let mut acc = crate::lib::std::vec::Vec::with_capacity(4); - let mut i = i.clone(); loop { - match f(i.clone()) { + match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, acc)), Err(e) => return Err(e), Ok((i1, o)) => { @@ -63,6 +64,7 @@ where // 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<I, O, E, F>(input: I, f: F) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, @@ -80,12 +82,12 @@ where /// # Arguments /// * `f` The parser to apply. /// -/// *Note*: if the parser passed to `many1` accepts empty inputs +/// *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 +/// to prevent going into an infinite loop. /// /// ```rust -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many1; /// use nom::bytes::complete::tag; /// @@ -95,38 +97,36 @@ where /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); -/// assert_eq!(parser("123123"), Err(Err::Error(("123123", ErrorKind::Tag)))); -/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); +/// 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")] -pub fn many1<I, O, E, F>(f: F) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn many1<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { - move |i: I| { - let mut i = i.clone(); - match f(i.clone()) { - Err(Err::Error(err)) => return Err(Err::Error(E::append(i, ErrorKind::Many1, err))), - Err(e) => return Err(e), - Ok((i1, o)) => { - let mut acc = crate::lib::std::vec::Vec::with_capacity(4); - acc.push(o); - i = i1; - - loop { - match f(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); + 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); } } } @@ -137,9 +137,10 @@ where // 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<I, O, E, F>(input: I, f: F) -> IResult<I, Vec<O>, E> where - I: Clone + Copy + PartialEq, + I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, E: ParseError<I>, { @@ -150,7 +151,7 @@ where /// a result. Returns a pair consisting of the results of /// `f` in a `Vec` and the result of `g`. /// ```rust -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many_till; /// use nom::bytes::complete::tag; /// @@ -159,29 +160,31 @@ where /// }; /// /// assert_eq!(parser("abcabcend"), Ok(("", (vec!["abc", "abc"], "end")))); -/// assert_eq!(parser("abc123end"), Err(Err::Error(("123end", ErrorKind::Tag)))); -/// assert_eq!(parser("123123end"), Err(Err::Error(("123123end", ErrorKind::Tag)))); -/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); +/// 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")] -pub fn many_till<I, O, P, E, F, G>(f: F, g: G) -> impl Fn(I) -> IResult<I, (Vec<O>, P), E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn many_till<I, O, P, E, F, G>( + mut f: F, + mut g: G, +) -> impl FnMut(I) -> IResult<I, (Vec<O>, P), E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(I) -> IResult<I, P, E>, + F: Parser<I, O, E>, + G: Parser<I, P, E>, E: ParseError<I>, { - move |i: I| { + move |mut i: I| { let mut res = crate::lib::std::vec::Vec::new(); - let mut i = i.clone(); loop { - match g(i.clone()) { + match g.parse(i.clone()) { Ok((i1, o)) => return Ok((i1, (res, o))), Err(Err::Error(_)) => { - match f(i.clone()) { - Err(Err::Error(err)) => - return Err(Err::Error(E::append(i, ErrorKind::ManyTill, err))), + 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) @@ -193,7 +196,7 @@ where i = i1; } } - }, + } Err(e) => return Err(e), } } @@ -203,6 +206,7 @@ where // 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, O, P, E, F, G>(i: I, f: F, g: G) -> IResult<I, (Vec<O>, P), E> where I: Clone + PartialEq, @@ -221,11 +225,11 @@ where /// /// ```rust /// # use nom::{Err, error::ErrorKind, Needed, IResult}; -/// use nom::multi::separated_list; +/// use nom::multi::separated_list0; /// use nom::bytes::complete::tag; /// /// fn parser(s: &str) -> IResult<&str, Vec<&str>> { -/// separated_list(tag("|"), tag("abc"))(s) +/// separated_list0(tag("|"), tag("abc"))(s) /// } /// /// assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"]))); @@ -235,32 +239,31 @@ where /// assert_eq!(parser("def|abc"), Ok(("def|abc", vec![]))); /// ``` #[cfg(feature = "alloc")] -pub fn separated_list<I, O, O2, E, F, G>(sep: G, f: F) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn separated_list0<I, O, O2, E, F, G>( + mut sep: G, + mut f: F, +) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(I) -> IResult<I, O2, E>, + F: Parser<I, O, E>, + G: Parser<I, O2, E>, E: ParseError<I>, { - move |i: I| { + move |mut i: I| { let mut res = Vec::new(); - let mut i = i.clone(); - match f(i.clone()) { + match f.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, o)) => { - if i1 == i { - return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); - } - res.push(o); i = i1; } } loop { - match sep(i.clone()) { + match sep.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, _)) => { @@ -268,14 +271,10 @@ where return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); } - match f(i1.clone()) { + match f.parse(i1.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i2, o)) => { - if i2 == i { - return Err(Err::Error(E::from_error_kind(i2, ErrorKind::SeparatedList))); - } - res.push(o); i = i2; } @@ -289,14 +288,15 @@ where // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] -pub fn separated_listc<I, O, O2, E, F, G>(i: I, sep: G, f: F) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn separated_list0c<I, O, O2, E, F, G>(i: I, sep: G, f: F) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, G: Fn(I) -> IResult<I, O2, E>, E: ParseError<I>, { - separated_list(sep, f)(i) + separated_list0(sep, f)(i) } /// Alternates between two parsers to produce @@ -307,47 +307,46 @@ where /// * `f` Parses the elements of the list. /// ```rust /// # #[macro_use] extern crate nom; -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; -/// use nom::multi::separated_nonempty_list; +/// # 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_nonempty_list(tag("|"), tag("abc"))(s) +/// 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(("", ErrorKind::Tag)))); -/// assert_eq!(parser("def|abc"), Err(Err::Error(("def|abc", ErrorKind::Tag)))); +/// 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")] -pub fn separated_nonempty_list<I, O, O2, E, F, G>(sep: G, f: F) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn separated_list1<I, O, O2, E, F, G>( + mut sep: G, + mut f: F, +) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(I) -> IResult<I, O2, E>, + F: Parser<I, O, E>, + G: Parser<I, O2, E>, E: ParseError<I>, { - move |i: I| { + move |mut i: I| { let mut res = Vec::new(); - let mut i = i.clone(); // Parse the first element - match f(i.clone()) { - Err(e)=> return Err(e), + match f.parse(i.clone()) { + Err(e) => return Err(e), Ok((i1, o)) => { - if i1 == i { - return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); - } - res.push(o); i = i1; } } loop { - match sep(i.clone()) { + match sep.parse(i.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i1, _)) => { @@ -355,14 +354,10 @@ where return Err(Err::Error(E::from_error_kind(i1, ErrorKind::SeparatedList))); } - match f(i1.clone()) { + match f.parse(i1.clone()) { Err(Err::Error(_)) => return Ok((i, res)), Err(e) => return Err(e), Ok((i2, o)) => { - if i2 == i { - return Err(Err::Error(E::from_error_kind(i2, ErrorKind::SeparatedList))); - } - res.push(o); i = i2; } @@ -376,14 +371,15 @@ where // this implementation is used for type inference issues in macros #[doc(hidden)] #[cfg(feature = "alloc")] -pub fn separated_nonempty_listc<I, O, O2, E, F, G>(i: I, sep: G, f: F) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn separated_list1c<I, O, O2, E, F, G>(i: I, sep: G, f: F) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, G: Fn(I) -> IResult<I, O2, E>, E: ParseError<I>, { - separated_nonempty_list(sep, f)(i) + separated_list1(sep, f)(i) } /// Repeats the embedded parser `n` times or until it fails @@ -410,40 +406,33 @@ where /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` #[cfg(feature = "alloc")] -pub fn many_m_n<I, O, E, F>(m: usize, n: usize, f: F) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn many_m_n<I, O, E, F>( + min: usize, + max: usize, + mut parse: F, +) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { - move |i: I| { - let mut res = crate::lib::std::vec::Vec::with_capacity(m); - let mut input = i.clone(); - let mut count: usize = 0; + move |mut input: I| { + let mut res = crate::lib::std::vec::Vec::with_capacity(min); - if n == 0 { - return Ok((i, vec!())) - } - - loop { - let _i = input.clone(); - match f(_i) { - Ok((i, o)) => { + 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 i == input { + if tail == input { return Err(Err::Error(E::from_error_kind(input, ErrorKind::ManyMN))); } - res.push(o); - input = i; - count += 1; - - if count == n { - return Ok((input, res)); - } + res.push(value); + input = tail; } Err(Err::Error(e)) => { - if count < m { + if count < min { return Err(Err::Error(E::append(input, ErrorKind::ManyMN, e))); } else { return Ok((input, res)); @@ -454,6 +443,8 @@ where } } } + + Ok((input, res)) } } @@ -488,19 +479,19 @@ where /// assert_eq!(parser("123123"), Ok(("123123", 0))); /// assert_eq!(parser(""), Ok(("", 0))); /// ``` -pub fn many0_count<I, O, E, F>(f: F) -> impl Fn(I) -> IResult<I, usize, E> +pub fn many0_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { move |i: I| { - let mut input = i.clone(); + let mut input = i; let mut count = 0; loop { let input_ = input.clone(); - match f(input_) { + match f.parse(input_) { Ok((i, _)) => { // loop trip must always consume (otherwise infinite loops) if i == input { @@ -537,7 +528,7 @@ where /// * `f` The parser to apply. /// ```rust /// # #[macro_use] extern crate nom; -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many1_count; /// use nom::bytes::complete::tag; /// @@ -547,18 +538,18 @@ where /// /// assert_eq!(parser("abcabc"), Ok(("", 2))); /// assert_eq!(parser("abc123"), Ok(("123", 1))); -/// assert_eq!(parser("123123"), Err(Err::Error(("123123", ErrorKind::Many1Count)))); -/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Many1Count)))); +/// 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<I, O, E, F>(f: F) -> impl Fn(I) -> IResult<I, usize, E> +pub fn many1_count<I, O, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, usize, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { move |i: I| { let i_ = i.clone(); - match f(i_) { + match f.parse(i_) { Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1Count))), Err(i) => Err(i), Ok((i1, _)) => { @@ -567,7 +558,7 @@ where loop { let input_ = input.clone(); - match f(input_) { + match f.parse(input_) { Err(Err::Error(_)) => return Ok((input, count)), Err(e) => return Err(e), Ok((i, _)) => { @@ -602,7 +593,7 @@ where /// * `count` How often to apply the parser. /// ```rust /// # #[macro_use] extern crate nom; -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::count; /// use nom::bytes::complete::tag; /// @@ -611,25 +602,26 @@ where /// } /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); -/// assert_eq!(parser("abc123"), Err(Err::Error(("123", ErrorKind::Tag)))); -/// assert_eq!(parser("123123"), Err(Err::Error(("123123", ErrorKind::Tag)))); -/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); +/// 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")] -pub fn count<I, O, E, F>(f: F, count: usize) -> impl Fn(I) -> IResult<I, Vec<O>, E> +#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))] +pub fn count<I, O, E, F>(mut f: F, count: usize) -> impl FnMut(I) -> IResult<I, Vec<O>, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, + F: Parser<I, O, E>, E: ParseError<I>, { - move |i: I | { + move |i: I| { let mut input = i.clone(); - let mut res = crate::lib::std::vec::Vec::new(); + let mut res = crate::lib::std::vec::Vec::with_capacity(count); for _ in 0..count { let input_ = input.clone(); - match f(input_) { + match f.parse(input_) { Ok((i, o)) => { res.push(o); input = i; @@ -647,6 +639,58 @@ where } } +/// 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<I, (), E> + 'a +where + I: Clone + PartialEq, + F: Fn(I) -> IResult<I, O, E> + 'a, + E: ParseError<I>, +{ + 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 @@ -676,21 +720,25 @@ where /// assert_eq!(parser("123123"), Ok(("123123", vec![]))); /// assert_eq!(parser(""), Ok(("", vec![]))); /// ``` -pub fn fold_many0<I, O, E, F, G, R>(f: F, init: R, g: G) -> impl Fn(I) -> IResult<I, R, E> +pub fn fold_many0<I, O, E, F, G, R>( + mut f: F, + init: R, + mut g: G, +) -> impl FnMut(I) -> IResult<I, R, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(R, O) -> R, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, E: ParseError<I>, R: Clone, { move |i: I| { let mut res = init.clone(); - let mut input = i.clone(); + let mut input = i; loop { let i_ = input.clone(); - match f(i_) { + match f.parse(i_) { Ok((i, o)) => { // loop trip must always consume (otherwise infinite loops) if i == input { @@ -716,7 +764,7 @@ pub fn fold_many0c<I, O, E, F, G, R>(i: I, f: F, init: R, g: G) -> IResult<I, R, where I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, - G: Fn(R, O) -> R, + G: FnMut(R, O) -> R, E: ParseError<I>, R: Clone, { @@ -734,7 +782,7 @@ where /// the current accumulator. /// ```rust /// # #[macro_use] extern crate nom; -/// # use nom::{Err, error::ErrorKind, Needed, IResult}; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::fold_many1; /// use nom::bytes::complete::tag; /// @@ -751,30 +799,34 @@ where /// /// assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"]))); /// assert_eq!(parser("abc123"), Ok(("123", vec!["abc"]))); -/// assert_eq!(parser("123123"), Err(Err::Error(("123123", ErrorKind::Many1)))); -/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Many1)))); +/// 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<I, O, E, F, G, R>(f: F, init: R, g: G) -> impl Fn(I) -> IResult<I, R, E> +pub fn fold_many1<I, O, E, F, G, R>( + mut f: F, + init: R, + mut g: G, +) -> impl FnMut(I) -> IResult<I, R, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(R, O) -> R, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, E: ParseError<I>, R: Clone, { move |i: I| { let _i = i.clone(); let init = init.clone(); - match f(_i) { + match f.parse(_i) { Err(Err::Error(_)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Many1))), - Err(e) => return Err(e), + Err(e) => Err(e), Ok((i1, o1)) => { let mut acc = g(init, o1); let mut input = i1; loop { let _input = input.clone(); - match f(_input) { + match f.parse(_input) { Err(Err::Error(_)) => { break; } @@ -801,7 +853,7 @@ pub fn fold_many1c<I, O, E, F, G, R>(i: I, f: F, init: R, g: G) -> IResult<I, R, where I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, - G: Fn(R, O) -> R, + G: FnMut(R, O) -> R, E: ParseError<I>, R: Clone, { @@ -844,34 +896,40 @@ where /// assert_eq!(parser(""), Ok(("", vec![]))); /// assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"]))); /// ``` -pub fn fold_many_m_n<I, O, E, F, G, R>(m: usize, n: usize, f: F, init: R, g: G) -> impl Fn(I) ->IResult<I, R, E> +pub fn fold_many_m_n<I, O, E, F, G, R>( + min: usize, + max: usize, + mut parse: F, + init: R, + mut fold: G, +) -> impl FnMut(I) -> IResult<I, R, E> where I: Clone + PartialEq, - F: Fn(I) -> IResult<I, O, E>, - G: Fn(R, O) -> R, + F: Parser<I, O, E>, + G: FnMut(R, O) -> R, E: ParseError<I>, R: Clone, { - move |i: I| { + move |mut input: I| { let mut acc = init.clone(); - let mut input = i.clone(); - for count in 0..n { - let _input = input.clone(); - match f(_input) { - Ok((i, o)) => { + 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 i == input { - return Err(Err::Error(E::from_error_kind(i, ErrorKind::ManyMN))); + if tail == input { + return Err(Err::Error(E::from_error_kind(tail, ErrorKind::ManyMN))); } - acc = g(acc, o); - input = i; + acc = fold(acc, value); + input = tail; } //FInputXMError: handle failure properly - Err(Err::Error(_)) => if count < m { - return Err(Err::Error(E::from_error_kind(i, ErrorKind::ManyMN))); - } else { - break; + Err(Err::Error(err)) => { + if count < min { + return Err(Err::Error(E::append(input, ErrorKind::ManyMN, err))); + } else { + break; + } } Err(e) => return Err(e), } @@ -882,7 +940,14 @@ where } #[doc(hidden)] -pub fn fold_many_m_nc<I, O, E, F, G, R>(i: I, m: usize, n: usize, f: F, init: R, g: G) -> IResult<I, R, E> +pub fn fold_many_m_nc<I, O, E, F, G, R>( + input: I, + min: usize, + max: usize, + parse: F, + init: R, + fold: G, +) -> IResult<I, R, E> where I: Clone + PartialEq, F: Fn(I) -> IResult<I, O, E>, @@ -890,19 +955,18 @@ where E: ParseError<I>, R: Clone, { - fold_many_m_n(m, n, f, init, g)(i) + 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. +/// 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::Needed::Size; /// use nom::number::complete::be_u16; /// use nom::multi::length_data; /// use nom::bytes::complete::tag; @@ -912,22 +976,25 @@ where /// } /// /// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); -/// assert_eq!(parser(b"\x00\x03"), Err(Err::Incomplete(Size(3)))); +/// assert_eq!(parser(b"\x00\x03a"), Err(Err::Incomplete(Needed::new(2)))); /// ``` -pub fn length_data<I, N, E, F>(f: F) -> impl Fn(I) -> IResult<I, I, E> +pub fn length_data<I, N, E, F>(mut f: F) -> impl FnMut(I) -> IResult<I, I, E> where - I: Clone + InputLength + InputTake, - N: Copy + ToUsize, - F: Fn(I) -> IResult<I, N, E>, + I: InputLength + InputTake, + N: ToUsize, + F: Parser<I, N, E>, E: ParseError<I>, { move |i: I| { - let (i, length) = f(i)?; + let (i, length) = f.parse(i)?; let length: usize = length.to_usize(); - if i.input_len() < length { - Err(Err::Incomplete(Needed::Size(length))) + 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)) } @@ -937,14 +1004,13 @@ where /// 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. +/// 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::ErrorKind, Needed, IResult}; -/// # use nom::Needed::Size; +/// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::number::complete::be_u16; /// use nom::multi::length_value; /// use nom::bytes::complete::tag; @@ -954,31 +1020,33 @@ where /// } /// /// assert_eq!(parser(b"\x00\x03abcefg"), Ok((&b"efg"[..], &b"abc"[..]))); -/// assert_eq!(parser(b"\x00\x03123123"), Err(Err::Error((&b"123"[..], ErrorKind::Tag)))); -/// assert_eq!(parser(b"\x00\x03"), Err(Err::Incomplete(Size(3)))); +/// 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<I, O, N, E, F, G>(f: F, g: G) -> impl Fn(I) -> IResult<I, O, E> +pub fn length_value<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, O, E> where I: Clone + InputLength + InputTake, - N: Copy + ToUsize, - F: Fn(I) -> IResult<I, N, E>, - G: Fn(I) -> IResult<I, O, E>, + N: ToUsize, + F: Parser<I, N, E>, + G: Parser<I, O, E>, E: ParseError<I>, { move |i: I| { - let (i, length) = f(i)?; + let (i, length) = f.parse(i)?; let length: usize = length.to_usize(); - if i.input_len() < length { - Err(Err::Incomplete(Needed::Size(length))) + 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(i.clone()) { - Err(Err::Incomplete(_)) => - Err(Err::Error(E::from_error_kind(i, ErrorKind::Complete))), + 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)), + Ok((_, o)) => Ok((rest, o)), } } } @@ -988,10 +1056,67 @@ where pub fn length_valuec<I, O, N, E, F, G>(i: I, f: F, g: G) -> IResult<I, O, E> where I: Clone + InputLength + InputTake, - N: Copy + ToUsize, + N: ToUsize, F: Fn(I) -> IResult<I, N, E>, G: Fn(I) -> IResult<I, O, E>, E: ParseError<I>, { 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<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl FnMut(I) -> IResult<I, Vec<O>, E> +where + I: Clone, + N: ToUsize, + F: Parser<I, N, E>, + G: Parser<I, O, E>, + E: ParseError<I>, +{ + 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)) + } +} |