summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-11-26 19:22:50 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-11-26 19:22:50 +0000
commit67861a4df8a5abdd70651d47cf265b20c41d2acc (patch)
treed864c573028c92da50cbb7d6e68acefa153ba9c5
parent8be071ab980c6080732daec565c35de242eaccf7 (diff)
downloadmon-67861a4df8a5abdd70651d47cf265b20c41d2acc.tar.gz
add SeparatedByWithOptTrailing combinator
-rw-r--r--src/lib.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0d5a164..220adb5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -190,6 +190,19 @@ pub trait Parser<I: Input>: Sized {
}
}
+ fn separated_by_with_opt_trailing<P>(
+ self,
+ delimiter: P,
+ ) -> impl ParserIter<I, Item = Self::Output>
+ where
+ P: Parser<I>,
+ {
+ SeparatedByWithOptTrailing {
+ parser: self,
+ delimiter,
+ }
+ }
+
fn find(self) -> impl ParserIter<I, Item = Self::Output> {
Find { parser: self }
}
@@ -342,6 +355,42 @@ where
}
}
+struct SeparatedByWithOptTrailing<P1, P2> {
+ parser: P1,
+ delimiter: P2,
+}
+
+impl<I, P1, P2> ParserIter<I> for SeparatedByWithOptTrailing<P1, P2>
+where
+ I: Input,
+ P1: Parser<I>,
+ P2: Parser<I>,
+{
+ type Item = P1::Output;
+
+ fn next<OM: Mode, EM: Mode>(
+ &self,
+ it: InputIter<I>,
+ _: &mut ParserIterState,
+ ) -> Option<ParserResult<I, Self::Item, OM, EM>> {
+ if it.is_finished() {
+ None
+ } else {
+ let (rest, output) = match self.parser.run::<OM, EM>(it) {
+ Ok((rest, output)) => (rest, output),
+ Err(rest) => return Some(Err(rest)),
+ };
+
+ let rest = match self.delimiter.check(rest.clone()) {
+ Ok((rest, _)) => rest,
+ _ => rest,
+ };
+
+ Some(Ok((rest, output)))
+ }
+ }
+}
+
struct AtLeast<P> {
parser: P,
count: usize,