feat: add optional modifier.
This commit is contained in:
		@@ -3,7 +3,7 @@ mod primitive_parsers;
 | 
			
		||||
 | 
			
		||||
use crate::parser::modified_parsers::{
 | 
			
		||||
    BindParser, ConvertParser, LitervalCountParser, LitervalParser, LookAheadParser, MapParser,
 | 
			
		||||
    NextParser, ReverseParser, TryParser,
 | 
			
		||||
    NextParser, OptionalParser, ReverseParser, TryParser,
 | 
			
		||||
};
 | 
			
		||||
use crate::parser::primitive_parsers::{
 | 
			
		||||
    AnyParser, FailParser, FailWithMessageParser, SatifiedMapParser, SatisfyParser, SkipParser,
 | 
			
		||||
@@ -200,6 +200,13 @@ where
 | 
			
		||||
            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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use super::*;
 | 
			
		||||
@@ -414,4 +435,16 @@ mod test {
 | 
			
		||||
            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)
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user