use crate::combinators::separated_by::SeparatedBy; use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput, Representation}; pub fn repeated<'a, P, I, O>(parser: P) -> Repeated<'a, I, O> where P: Parser + 'a, I: ParserInput + Clone + 'a, { Repeated { inner_parser: BoxedParser::new(parser), at_least: None, at_most: None, } } pub struct Repeated<'a, I, O> where I: ParserInput + Clone, { pub(super) inner_parser: BoxedParser<'a, I, O, I>, pub(super) at_least: Option, pub(super) at_most: Option, } impl<'a, I, O> Repeated<'a, I, O> where I: ParserInput + Clone, { pub fn at_least(self, n: u16) -> Self { Self { at_least: Some(n), ..self } } pub fn at_most(self, n: u16) -> Self { Self { at_most: Some(n), ..self } } pub fn separated_by(self, delimiter: D, allow_trailing: bool) -> SeparatedBy<'a, I, O> where D: Parser + 'a, O2: 'a, I: 'a, { SeparatedBy { inner_repeated: self, delimiter: BoxedParser::new(delimiter.to(())), allow_trailing, } } } impl<'a, I, O> Parser, I> for Repeated<'a, I, O> where I: ParserInput + Clone + 'a, { fn parse(&self, input: I) -> ParseResult, I> { let at_least = self.at_least.unwrap_or(0); let at_most = self.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_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)) } fn representation(&self) -> Representation { Representation::repeated( self.inner_parser.representation(), self.at_least.unwrap_or(0), self.at_most.unwrap_or(u16::MAX), ) } }