use crate::{collector::*, mapper::Mapper};
pub struct FnCollector<TFn>(pub TFn);
impl<'a,T,TFn> Mapper<T> for FnCollector<TFn> {
type Output=T;
fn map(self,value:T)->(Self::Output,Self) {
(value,self)
}
}
impl<'a,Input,Next,Output,TFn> Collector<Input,Next> for FnCollector<TFn>
where TFn:Fn(Input,Next)->Output
{
type Output=Output;
fn collect(mut self,value:Input,next:Next)->(<Self as Collector<Input,Next>>::Output,Self) {
((self.0)(value,next),self)
}
}
pub struct FnMutCollector<TFn>(pub TFn);
impl<'a,T,TFn> Mapper<T> for FnMutCollector<TFn> {
type Output=T;
fn map(self,value:T)->(Self::Output,Self) {
(value,self)
}
}
impl<'a,Input,Next,Output,TFn> Collector<Input,Next> for FnMutCollector<TFn>
where TFn:FnMut(Input,Next)->Output
{
type Output=Output;
fn collect(mut self,value:Input,next:Next)->(<Self as Collector<Input,Next>>::Output,Self) {
((self.0)(value,next),self)
}
}
pub struct MapperCollector<TMapper,TCollector>(pub TMapper,pub TCollector);
impl<'a,TMapper,TCollector,Input> Mapper<Input> for MapperCollector<TMapper,TCollector>
where TMapper:Mapper<Input>,
TCollector:Mapper< <TMapper as Mapper<Input>>::Output >
{
type Output=< TCollector as Mapper< <TMapper as Mapper<Input>>::Output >>::Output;
fn map(self,value:Input)->(Self::Output,Self) {
let (ma,mb)=(self.0,self.1);
let (v1,ma2)=ma.map(value);
let (v2,mb2)=mb.map(v1);
return (v2,MapperCollector(ma2,mb2));
}
}
impl <'a,TMapper,TCollector,Input,TNext> Collector<Input,TNext> for MapperCollector<TMapper,TCollector>
where TMapper:Mapper<Input>,
TCollector:Collector<<TMapper as Mapper<Input>>::Output,TNext>
{
type Output= <TCollector as Collector<<TMapper as Mapper<Input>>::Output,TNext>>::Output ;
fn collect(self,value:Input,next:TNext)->(<Self as Collector<Input,TNext>>::Output,Self) {
let (m,c)=(self.0,self.1);
let (v1,m2)=m.map(value);
let (r,c2)=c.collect(v1, next);
return (r,MapperCollector(m2,c2));
}
}
impl Mapper<()> for () {
type Output=();
fn map(self,_value:())->(Self::Output,()) {((),())}
}
impl Collector<(),()> for () {
type Output=();
fn collect(self,_value:(),_next:())->((),()) {((),())}
}