feat: add optional modifier.
This commit is contained in:
parent
3e6c2c9bde
commit
9da7290da5
|
@ -3,7 +3,7 @@ mod primitive_parsers;
|
||||||
|
|
||||||
use crate::parser::modified_parsers::{
|
use crate::parser::modified_parsers::{
|
||||||
BindParser, ConvertParser, LitervalCountParser, LitervalParser, LookAheadParser, MapParser,
|
BindParser, ConvertParser, LitervalCountParser, LitervalParser, LookAheadParser, MapParser,
|
||||||
NextParser, ReverseParser, TryParser,
|
NextParser, OptionalParser, ReverseParser, TryParser,
|
||||||
};
|
};
|
||||||
use crate::parser::primitive_parsers::{
|
use crate::parser::primitive_parsers::{
|
||||||
AnyParser, FailParser, FailWithMessageParser, SatifiedMapParser, SatisfyParser, SkipParser,
|
AnyParser, FailParser, FailWithMessageParser, SatifiedMapParser, SatisfyParser, SkipParser,
|
||||||
|
@ -200,6 +200,13 @@ where
|
||||||
phantom_data: PhantomData,
|
phantom_data: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn optional(self) -> OptionalParser<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
OptionalParser { parser: self }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TToken, T: 'a, TContext, F> Parser<'a, TToken, T, TContext> for F
|
impl<'a, TToken, T: 'a, TContext, F> Parser<'a, TToken, T, TContext> for F
|
||||||
|
|
|
@ -240,6 +240,27 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct OptionalParser<P> {
|
||||||
|
pub(crate) parser: P,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, TToken, T: 'a, TContext, P> Parser<'a, TToken, Option<T>, TContext> for OptionalParser<P>
|
||||||
|
where
|
||||||
|
TToken: Debug + Clone,
|
||||||
|
P: Parser<'a, TToken, T, TContext>,
|
||||||
|
{
|
||||||
|
fn parse(
|
||||||
|
&self,
|
||||||
|
context: Rc<RefCell<ParserContext<TToken, TContext>>>,
|
||||||
|
input: &'a [TToken],
|
||||||
|
) -> ParserResult<'a, TToken, Option<T>> {
|
||||||
|
match self.parser.parse(context, input) {
|
||||||
|
Ok(r) => Ok((r.0, Some(r.1))),
|
||||||
|
Err(r) => Ok((r.input, None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -414,4 +435,16 @@ mod test {
|
||||||
char_parser('a').reverse(()).parse(c, i)
|
char_parser('a').reverse(()).parse(c, i)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn optional_test() {
|
||||||
|
parser_test_helper(
|
||||||
|
ParserContext::new_with_str("abc", ()),
|
||||||
|
&Some('a'),
|
||||||
|
|c, i| char_parser('a').optional().parse(c, i),
|
||||||
|
);
|
||||||
|
parser_test_helper(ParserContext::new_with_str("bc", ()), &None, |c, i| {
|
||||||
|
char_parser('a').optional().parse(c, i)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user