From 06ba380db8bd49067abedab2370c4881812d5316 Mon Sep 17 00:00:00 2001 From: Jonathan Giroux Date: Sun, 18 Sep 2022 18:48:56 +0200 Subject: [PATCH] feat: add `cond_opt` --- src/combinator/mod.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/combinator/mod.rs b/src/combinator/mod.rs index 7071cc7f3..dfeda2a69 100644 --- a/src/combinator/mod.rs +++ b/src/combinator/mod.rs @@ -285,6 +285,39 @@ where } } +/// Calls the parser contained in an [`Option`], if any. +/// +/// ```rust +/// # use nom::{Err, error::{Error, ErrorKind}, IResult}; +/// use nom::combinator::cond_opt; +/// use nom::character::complete::alpha1; +/// # fn main() { +/// +/// fn parser<'a>(opt: Option IResult<&'a str, &'a str, Error<&'a str>>>, i: &'a str) -> IResult<&'a str, Option<&'a str>> { +/// cond_opt(opt)(i) +/// }; +/// +/// assert_eq!(parser(Some(alpha1), "abcd;"), Ok((";", Some("abcd")))); +/// assert_eq!(parser(None, "abcd;"), Ok(("abcd;", None))); +/// assert_eq!(parser(Some(alpha1), "123;"), Err(Err::Error(Error::new("123;", ErrorKind::Alpha)))); +/// assert_eq!(parser(None, "123;"), Ok(("123;", None))); +/// # } +/// ``` +pub fn cond_opt, F>( + mut opt: Option, +) -> impl FnMut(I) -> IResult, E> +where + F: Parser, +{ + move |input: I| match &mut opt { + Some(f) => match f.parse(input) { + Ok((i, o)) => Ok((i, Some(o))), + Err(e) => Err(e), + }, + None => Ok((input, None)), + } +} + /// Tries to apply its parser without consuming the input. /// /// ```rust