use std::marker::PhantomData;
use crate::{
error::Error,
prelude::{PInput, PSuccess, Parser, ParserCore},
};
#[derive(Clone)]
pub struct PFoldLeft<P, TP, F, I, O2> {
head: P,
tail: TP,
f: F,
_marker: PhantomData<I>,
_marker2: PhantomData<O2>,
}
pub fn pfoldl<P, TP, F, I, O2>(head: P, tail: TP, f: F) -> PFoldLeft<P, TP, F, I, O2> {
PFoldLeft {
head,
tail,
f,
_marker: PhantomData,
_marker2: PhantomData,
}
}
impl<'a, K, O, P, TP, F, I, O2> ParserCore<'a, K, O> for PFoldLeft<P, TP, F, I, O2>
where
K: PartialEq + Clone + 'a,
O: Clone + 'a,
P: Parser<'a, K, O>,
I: IntoIterator<Item = O2> + Clone + 'a,
TP: Parser<'a, K, I>,
F: Fn(O, O2) -> O + Clone + 'a,
{
fn parse(&self, i: PInput<'a, K>) -> Result<PSuccess<'a, K, O>, Error<'a, K>> {
let PSuccess { val: head, rest } = self.head.parse(i)?;
let PSuccess { val: tail, rest } = self.tail.parse(rest)?;
let res = tail.into_iter().fold(head, |acc, next| (self.f)(acc, next));
Ok(PSuccess { val: res, rest })
}
}
impl<'a, K, O, P, TP, F, I, O2> Parser<'a, K, O> for PFoldLeft<P, TP, F, I, O2>
where
K: PartialEq + Clone + 'a,
O: Clone + 'a,
O2: Clone + 'a,
P: Parser<'a, K, O>,
I: IntoIterator<Item = O2> + Clone + 'a,
TP: Parser<'a, K, I>,
F: Fn(O, O2) -> O + Clone + 'a,
{
}