use crate::combinators::repeated::Repeated; use crate::parser::{BoxedParser, ParseResult, Parser, ParserInput, Representation}; pub struct SeparatedBy<'a, I, O> where I: ParserInput + Clone, { pub(super) inner_repeated: Repeated<'a, I, O>, pub(super) delimiter: BoxedParser<'a, I, (), I>, pub(super) allow_trailing: bool, } impl<'a, I, O> Parser, I> for SeparatedBy<'a, I, O> where I: ParserInput + Clone + 'a, { fn representation(&self) -> Representation { Representation::new("sepby") } 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); let parser = &self.inner_repeated.inner_parser; let delimiter = &self.delimiter; if at_most == 0 { return Ok((vec![], input)); } let mut results = Vec::new(); let mut count: u16 = 0; let mut further_input; match parser.parse(input.clone()) { Ok((item, rest)) => { results.push(item); further_input = rest; } Err(_e) => { if at_least > 0 { return Err(input); } else { return Ok((vec![], input)); } } } loop { match delimiter.parse(further_input.clone()) { Ok(((), rest)) => { further_input = rest; } Err(_e) => { break; } } match parser.parse(further_input.clone()) { Ok((item, rest)) => { results.push(item); further_input = rest; count += 1; } Err(_e) if self.allow_trailing => { break; } Err(e) => { return Err(e); } } if count >= at_most { break; } } if count < at_least { return Err(input); } Ok((results, further_input)) } }