Start working on DelimitedBy

This commit is contained in:
Greg Shuflin 2022-10-20 18:35:59 -07:00
parent ed4567d881
commit d624a54fb0

View File

@ -48,6 +48,18 @@ where
..self ..self
} }
} }
pub fn delimited_by<D, O2>(self, delimiter: D) -> DelimitedBy<'a, I, O>
where
D: Parser<I, O2, I> + 'a,
O2: 'a,
I: 'a,
{
DelimitedBy {
inner_repeated: self,
delimiter: BoxedParser::new(delimiter.to(())),
}
}
} }
impl<'a, I, O> Parser<I, Vec<O>, I> for Repeated<'a, I, O> impl<'a, I, O> Parser<I, Vec<O>, 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, Vec<O>, I> for DelimitedBy<'a, I, O>
where
I: Clone + 'a,
{
fn parse(&self, input: I) -> ParseResult<I, Vec<O>, 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> pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O>
where where
P: Parser<I, O, I> + 'static, P: Parser<I, O, I> + 'static,