summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-10-24 00:26:51 -0400
committerJohn Turner <jturner.usa@gmail.com>2025-10-24 00:27:01 -0400
commitfc4ae140ac8d3dd40868a18d44dfb4cd46711129 (patch)
tree6d5db4978326143c878ed27bf6f66712cfb484f3
parent675b511c836163efee201fc0bb9ca67d1db28823 (diff)
downloadmon-fc4ae140ac8d3dd40868a18d44dfb4cd46711129.tar.gz
impl Verify combinator
-rw-r--r--src/lib.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6f16148..686ce6f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -170,6 +170,16 @@ pub trait Parser<I: Input>: Sized {
delimiter,
}
}
+
+ fn verify<C>(self, checker: C) -> impl Parser<I, Output = Self::Output>
+ where
+ C: Parser<I>,
+ {
+ Verify {
+ parser: self,
+ checker,
+ }
+ }
}
impl<I, O, F> Parser<I> for F
@@ -812,6 +822,33 @@ where
Opt { parser }
}
+struct Verify<P, C> {
+ parser: P,
+ checker: C,
+}
+
+impl<I, P, C> Parser<I> for Verify<P, C>
+where
+ I: Input,
+ P: Parser<I>,
+ C: Parser<I>,
+{
+ type Output = P::Output;
+
+ fn run<OM: Mode, EM: Mode, Tracer: Trace<I>>(
+ &mut self,
+ it: InputIter<I>,
+ ) -> ParserResult<I, Self::Output, OM, EM> {
+ match self.parser.run::<Emit, Emit, Tracer>(it.clone()) {
+ Ok((rest, output)) if self.checker.check(it.clone()).is_ok() => {
+ Ok((rest, OM::bind(|| output)))
+ }
+ Err(rest) => Err(EM::bind(|| rest)),
+ _ => Err(EM::bind(|| it)),
+ }
+ }
+}
+
pub fn alpha<I>() -> impl Parser<I, Output = I>
where
I: Input,