use crate::parser::*;
use std::marker::PhantomData;
pub struct PDelim<P1, P2, A> {
p: P1,
delim: P2,
_marker: PhantomData<A>,
}
pub fn pdelim<P1, P2, A>(p: P1, delim: P2) -> PDelim<P1, P2, A> {
PDelim {
p,
delim,
_marker: PhantomData,
}
}
impl<'a, K, O, P, PDelim_, B> ParserCore<'a, K, Vec<O>> for PDelim<P, PDelim_, B>
where
K: PartialEq + Clone + 'a,
O: 'a,
B: 'a,
P: Parser<'a, K, O>,
PDelim_: Parser<'a, K, B>,
{
fn parse(&self, i: PInput<'a, K>) -> Result<PSuccess<'a, K, Vec<O>>, PFail<'a, K>> {
let mut vals = vec![];
let mut input = i;
loop {
match self.p.parse(input.clone()) {
Ok(PSuccess { val, rest }) => {
vals.push(val);
input = rest;
match self.delim.parse(input.clone()) {
Ok(PSuccess { val: _, rest }) => {
input = rest;
continue;
}
Err(_) => {
return Ok(PSuccess {
val: vals,
rest: input,
});
}
}
}
Err(PFail { error, span, rest }) => {
if !vals.is_empty() {
return Ok(PSuccess { val: vals, rest });
} else {
return Err(PFail { error, span, rest });
}
}
}
}
}
}
impl<'a, K, O, P, PDelim_, B> Parser<'a, K, Vec<O>> for PDelim<P, PDelim_, B>
where
K: PartialEq + Clone + 'a,
O: 'a,
B: 'a,
P: Parser<'a, K, O>,
PDelim_: Parser<'a, K, B>,
{
}