diff --git a/src/combinator/mod.rs b/src/combinator/mod.rs index 7071cc7f3..fe08d4a10 100644 --- a/src/combinator/mod.rs +++ b/src/combinator/mod.rs @@ -218,7 +218,9 @@ where } } -/// Optional parser: Will return `None` if not successful. +/// Optional parser, will return `None` on [`Err::Error`]. +/// +/// To chain an error up, see [`cut`]. /// /// ```rust /// # use nom::{Err,error::ErrorKind, IResult}; @@ -575,18 +577,55 @@ where } } -/// transforms an error to failure +/// Transforms an [`Err::Error`] (recoverable) to [`Err::Failure`] (unrecoverable) +/// +/// This commits the parse result, preventing alternative branch paths like with +/// [`nom::branch::alt`][crate::branch::alt]. /// +/// # Example +/// +/// Without `cut`: /// ```rust /// # use nom::{Err,error::ErrorKind, IResult}; +/// # use nom::character::complete::{one_of, digit1}; +/// # use nom::combinator::rest; +/// # use nom::branch::alt; +/// # use nom::sequence::preceded; +/// # fn main() { +/// +/// fn parser(input: &str) -> IResult<&str, &str> { +/// alt(( +/// preceded(one_of("+-"), digit1), +/// rest +/// ))(input) +/// } +/// +/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); +/// assert_eq!(parser("ab"), Ok(("", "ab"))); +/// assert_eq!(parser("+"), Ok(("", "+"))); +/// # } +/// ``` +/// +/// With `cut`: +/// ```rust +/// # use nom::{Err,error::ErrorKind, IResult, error::Error}; +/// # use nom::character::complete::{one_of, digit1}; +/// # use nom::combinator::rest; +/// # use nom::branch::alt; +/// # use nom::sequence::preceded; /// use nom::combinator::cut; -/// use nom::character::complete::alpha1; /// # fn main() { /// -/// let mut parser = cut(alpha1); +/// fn parser(input: &str) -> IResult<&str, &str> { +/// alt(( +/// preceded(one_of("+-"), cut(digit1)), +/// rest +/// ))(input) +/// } /// -/// assert_eq!(parser("abcd;"), Ok((";", "abcd"))); -/// assert_eq!(parser("123;"), Err(Err::Failure(("123;", ErrorKind::Alpha)))); +/// assert_eq!(parser("+10 ab"), Ok((" ab", "10"))); +/// assert_eq!(parser("ab"), Ok(("", "ab"))); +/// assert_eq!(parser("+"), Err(Err::Failure(Error { input: "", code: ErrorKind::Digit }))); /// # } /// ``` pub fn cut, F>(mut parser: F) -> impl FnMut(I) -> IResult @@ -643,6 +682,8 @@ where /// Call the iterator's [ParserIterator::finish] method to get the remaining input if successful, /// or the error value if we encountered an error. /// +/// On [`Err::Error`], iteration will stop. To instead chain an error up, see [`cut`]. +/// /// ```rust /// use nom::{combinator::iterator, IResult, bytes::complete::tag, character::complete::alpha1, sequence::terminated}; /// use std::collections::HashMap; diff --git a/src/multi/mod.rs b/src/multi/mod.rs index 13acd75e9..dff28e60f 100644 --- a/src/multi/mod.rs +++ b/src/multi/mod.rs @@ -23,15 +23,16 @@ use core::num::NonZeroUsize; #[cfg(feature = "alloc")] const MAX_INITIAL_CAPACITY_BYTES: usize = 65536; -/// Repeats the embedded parser until it fails -/// and returns the results in a `Vec`. +/// Repeats the embedded parser, gathering the results in a `Vec`. +/// +/// This stops on [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. /// /// # 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 +/// *Note*: if the parser passed in 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}; @@ -76,10 +77,10 @@ where } } -/// 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. +/// Runs the embedded parser, gathering the results in a `Vec`. +/// +/// 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, +/// see [`cut`][crate::combinator::cut]. /// /// # Arguments /// * `f` The parser to apply. @@ -138,9 +139,12 @@ where } } -/// 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`. +/// Applies the parser `f` until the parser `g` produces a result. +/// +/// Returns a tuple of the results of `f` in a `Vec` and the result of `g`. +/// +/// `f` keeps going so long as `g` produces [`Err::Error`]. To instead chain an error up, see [`cut`][crate::combinator::cut]. +/// /// ```rust /// # use nom::{Err, error::{Error, ErrorKind}, Needed, IResult}; /// use nom::multi::many_till; @@ -195,8 +199,11 @@ where } } -/// Alternates between two parsers to produce -/// a list of elements. +/// Alternates between two parsers to produce a list of elements. +/// +/// This stops when either parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `sep` Parses the separator between list elements. /// * `f` Parses the elements of the list. @@ -265,9 +272,13 @@ where } } -/// Alternates between two parsers to produce -/// a list of elements. Fails if the element -/// parser does not produce at least one element. +/// Alternates between two parsers to produce a list of elements until [`Err::Error`]. +/// +/// Fails if the element parser does not produce at least one element.$ +/// +/// This stops when either parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `sep` Parses the separator between list elements. /// * `f` Parses the elements of the list. @@ -335,13 +346,20 @@ where } } -/// 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. +/// Repeats the embedded parser `m..=n` times +/// +/// This stops before `n` when the parser returns [`Err::Error`] and returns the results that were accumulated. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `m` The minimum number of iterations. /// * `n` The maximum number of iterations. /// * `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::ErrorKind, Needed, IResult}; /// use nom::multi::many_m_n; @@ -405,10 +423,17 @@ where } } -/// Repeats the embedded parser until it fails -/// and returns the number of successful iterations. +/// Repeats the embedded parser, counting the results +/// +/// This stops on [`Err::Error`]. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `f` The parser to apply. +/// +/// *Note*: if the parser passed in 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_count; @@ -455,12 +480,18 @@ where } } -/// 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. +/// Runs the embedded parser, counting the results. +/// +/// This stops on [`Err::Error`] if there is at least one result. To instead chain an error up, +/// see [`cut`][crate::combinator::cut]. +/// /// # 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_count; @@ -512,8 +543,8 @@ where } } -/// Runs the embedded parser a specified number -/// of times. Returns the results in a `Vec`. +/// Runs the embedded parser `count` times, gathering the results in a `Vec` +/// /// # Arguments /// * `f` The parser to apply. /// * `count` How often to apply the parser. @@ -565,8 +596,10 @@ 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. +/// 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 @@ -616,13 +649,20 @@ where } } -/// Applies a parser until it fails and accumulates -/// the results using a given function and initial value. +/// Repeats the embedded parser, calling `g` to gather the results. +/// +/// This stops on [`Err::Error`]. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `f` The parser to apply. /// * `init` A function returning the initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. +/// +/// *Note*: if the parser passed in 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::fold_many0; @@ -684,15 +724,21 @@ where } } -/// 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. +/// Repeats the embedded parser, calling `g` to gather the results. +/// +/// This stops on [`Err::Error`] if there is at least one result. To instead chain an error up, +/// see [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `f` The parser to apply. /// * `init` A function returning the initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. +/// +/// *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::fold_many1; @@ -762,10 +808,11 @@ where } } -/// 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. +/// Repeats the embedded parser `m..=n` times, calling `g` to gather the results +/// +/// This stops before `n` when the parser returns [`Err::Error`]. To instead chain an error up, see +/// [`cut`][crate::combinator::cut]. +/// /// # Arguments /// * `m` The minimum number of iterations. /// * `n` The maximum number of iterations. @@ -773,6 +820,11 @@ where /// * `init` A function returning the initial value. /// * `g` The function that combines a result of `f` with /// the current accumulator. +/// +/// *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::ErrorKind, Needed, IResult}; /// use nom::multi::fold_many_m_n;