optional combinator

This commit is contained in:
Greg Shuflin 2022-10-17 00:47:19 -07:00
parent 8b010811e3
commit a02accf08a
3 changed files with 24 additions and 1 deletions

View File

@ -1,5 +1,16 @@
use crate::parser::Parser;
pub fn optional<P, I, O, E>(parser: P) -> impl Parser<I, Option<O>, E>
where
P: Parser<I, O, E>,
I: Clone,
{
move |input: I| match parser.parse(input.clone()) {
Ok((output, rest)) => Ok((Some(output), rest)),
Err(_e) => Ok((None, input)),
}
}
pub fn map<P, F, I, O1, O2, E>(parser: P, map_fn: F) -> impl Parser<I, O2, E>
where
P: Parser<I, O1, E>,

View File

@ -12,7 +12,7 @@ pub use parser::{ParseResult, Parser};
mod tests {
use super::*;
use crate::choice::choice;
use crate::primitives::{any_char, literal, literal_char, pred};
use crate::primitives::{any_char, literal, literal_char, one_of, pred};
use crate::sequence::seq;
use std::collections::HashMap;
@ -48,6 +48,8 @@ mod tests {
literal("false").to(JsonValue::Bool(false)),
));
let digit = one_of("1234567890");
let json_string = seq((
literal_char('"'),
pred(any_char, |ch| *ch != '"'),

View File

@ -43,6 +43,16 @@ pub trait Parser<I, O, E> {
{
BoxedParser::new(crate::sequence::tuple2(self, next_parser))
}
fn optional<'a>(self) -> BoxedParser<'a, I, Option<O>, E>
where
I: Clone + 'a,
O: 'a,
E: 'a,
Self: Sized + 'a,
{
BoxedParser::new(crate::combinators::optional(self))
}
}
pub struct BoxedParser<'a, I, O, E> {