From d624a54fb01f8afb7fac20fe5da4723254b084f1 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Thu, 20 Oct 2022 18:35:59 -0700 Subject: [PATCH] Start working on DelimitedBy --- src/combinators.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/combinators.rs b/src/combinators.rs index 53fdd4e..b7302d0 100644 --- a/src/combinators.rs +++ b/src/combinators.rs @@ -48,6 +48,18 @@ where ..self } } + + pub fn delimited_by(self, delimiter: D) -> DelimitedBy<'a, I, O> + where + D: Parser + 'a, + O2: 'a, + I: 'a, + { + DelimitedBy { + inner_repeated: self, + delimiter: BoxedParser::new(delimiter.to(())), + } + } } impl<'a, I, O> Parser, I> for Repeated<'a, I, O> @@ -82,6 +94,50 @@ where } } +pub struct DelimitedBy<'a, I, O> +where + I: Clone, +{ + inner_repeated: Repeated<'a, I, O>, + delimiter: BoxedParser<'a, I, (), I>, +} + +impl<'a, I, O> Parser, I> for DelimitedBy<'a, I, O> +where + I: Clone + 'a, +{ + fn parse(&self, input: I) -> ParseResult, I> { + let at_least = self.inner_repeated.at_least.unwrap_or(0); + let at_most = self.inner_repeated.at_most.unwrap_or(u16::MAX); + + if at_most == 0 { + return Ok((vec![], input)); + } + + let mut results = Vec::new(); + let mut count: u16 = 0; + let mut further_input = input.clone(); + + while let Ok((item, rest)) = self + .inner_repeated + .inner_parser + .parse(further_input.clone()) + { + results.push(item); + further_input = rest; + count += 1; + if count >= at_most { + break; + } + } + if count < at_least { + return Err(input); + } + + Ok((results, further_input)) + } +} + pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O> where P: Parser + 'static,