use super::{collector::*, mapper::Mapper};
pub struct FnCollector<TFn>(pub TFn);
impl<'a,T,TFn> Mapper<T> for &'a FnCollector<TFn> {
type Output=T;
fn map(&self,value:T)->Self::Output {
value
}
}
impl<'a,Input,Next,Output,TFn> Collector<Input,Next> for &'a FnCollector<TFn>
where TFn:Fn(Input,Next)->Output
{
type Output=Output;
type NextCollector=&'a FnCollector<TFn>;
fn unwrap(self)->(Self::NextCollector,impl FnOnce(Input,Next)->Self::Output) {
(self,& self.0)
}
}
pub struct FnMutCollector<'a,TFn>(pub TFn);
impl<'a,T,TFn> Mapper<T> for FnMutCollector<'a,TFn> {
type Output=T;
fn map(& self,value:T)->Self::Output {
value
}
}
impl<'a,Input,Next,Output,TFn> Collector<Input,Next> for FnMutCollector<'a,TFn>
where TFn:Fn(Input,Next)->Output
{
type Output=Output;
type NextCollector=FnMutCollector<'a,TFn>;
fn unwrap(self)->(Self::NextCollector,impl FnOnce(Input,Next)->Self::Output) {
let aref=&self.0;
(self,aref)
}
}
pub struct MapperCollector<'a,TMapper,TCollector>(pub &'a TMapper,pub TCollector);
impl<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 {
let (ma,mb)=(self.0,self.1);
let v1=ma.map(value);
let v2=mb.map(v1);
return v2;
}
}
impl <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 ;
type NextCollector=MapperCollector<TMapper,TCollector::NextCollector>;
fn unwrap(self)->(Self::NextCollector,impl FnOnce(Input,TNext)->Self::Output) {
let (nc,f)=self.1.unwrap();
let refm=&self.0;
(
MapperCollector(self.0,nc),
|value:Input,next:TNext|{
let v_m=refm.map(value);
let v_r=f(v_m,next);
return v_r;
}
)
}
}
impl Mapper<()> for () {
type Output=();
fn map(&self,_value:())->(){()}
}
impl Collector<(),()> for () {
type Output=();
type NextCollector=();
fn unwrap(self)->(Self::NextCollector,impl FnOnce((),())->Self::Output) {
((),|a,b|{()})
}
}