parcos/combinators/
pred.rs

1use crate::{error::Error, parser::Parser, stream::Streamable};
2
3/// # Pred
4/// For parsing with an predicate (P).
5pub struct Pred<F>(F);
6
7impl<I: Clone, F: Fn(&I) -> bool> Parser<I, I> for Pred<F> {
8    fn parse_impl<S: Streamable<I>>(
9        &self,
10        stream: &mut S,
11        _: &mut Vec<Error<I>>,
12    ) -> (usize, Result<I, Error<I>>)
13    where
14        Self: Sized,
15    {
16        match stream.peek() {
17            Some(i) if (self.0)(i) => (1, Ok(stream.next().unwrap())),
18            i => {
19                let i = i.cloned();
20                (0, Err(Error::Unexpected(stream.position(), vec![], i)))
21            }
22        }
23    }
24}
25
26/// For constructing Pred.
27/// ```
28/// use parcos::{parser::Parser, combinators::pred};
29///
30/// let digit_parser = pred(|x: &char| x.is_ascii_digit());
31/// let parsed = digit_parser.parse("10x".chars());
32///
33/// assert!(parsed.is_ok());
34/// assert_eq!(parsed.unwrap(), '1');
35/// ```
36pub fn pred<I, F: Fn(&I) -> bool>(f: F) -> Pred<F> {
37    Pred(f)
38}