use crate::parser::{Input, Parser, ParseResult};
pub fn opt<'a, 'b, O, F>(mut f: F) -> impl FnMut(Input<'a>) -> ParseResult<'a, Option<O>>
where
O: 'b,
F: Parser<'a, 'b, O>,
{
move |input| match f.parse(input) {
Ok((value, input)) => Ok((Some(value), input)),
Err(_) => Ok((None, input)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::{prelude::*, Position};
#[test]
fn opt_none() {
let (output, input) = opt(tag("def"))(Input::new("abc")).expect("valid output");
assert_eq!(output, None);
assert_eq!(input, Input::from("abc"));
assert_eq!(input.position(), Position::new(0, 1, 1));
assert_eq!(input.current(), Some('a'));
let (output, input) = opt(tag("def"))(Input::new("")).expect("valid output");
assert_eq!(output, None);
assert_eq!(input, Input::from(""));
assert_eq!(input.position(), Position::new(0, 1, 1));
assert_eq!(input.current(), None);
}
#[test]
fn opt_some() {
let (output, input) = opt(tag("def"))(Input::new("defabc")).expect("valid output");
assert_eq!(output, Some("def"));
assert_eq!(input, Input::from("abc"));
assert_eq!(input.position(), Position::new(3, 1, 4));
assert_eq!(input.current(), Some('a'));
}
}