use std::marker::PhantomData;
use super::Transducer;
pub struct IdentityStep<'t, R, T> {
step: Box<Fn(R, T) -> R + 't>
}
impl<'t, R, T> FnOnce<(R, T)> for IdentityStep<'t, R, T> {
type Output = R;
extern "rust-call" fn call_once(self, args: (R, T)) -> R {
self.call(args)
}
}
impl<'t, R, T> FnMut<(R, T)> for IdentityStep<'t, R, T> {
extern "rust-call" fn call_mut(&mut self, args: (R, T)) -> R {
self.call(args)
}
}
impl<'t, R, T> Fn<(R, T)> for IdentityStep<'t, R, T> {
extern "rust-call" fn call(&self, (r, t): (R, T)) -> R {
(*self.step)(r, t)
}
}
pub struct Identity;
impl<'t, R: 't, T: 't> Transducer<'t, R, T, T> for Identity {
type Step = IdentityStep<'t, R, T>;
fn apply<Step: Fn(R, T) -> R + 't>(&self, step: Step) -> IdentityStep<'t, R, T> {
IdentityStep { step: Box::new(step) }
}
}
impl Identity {
pub fn new() -> Identity {
Identity
}
}
pub struct MappingStep<'t, R, T, F: 't> {
step: Box<Fn(R, T) -> R + 't>,
f: &'t F
}
impl<'t, R, T, U, F> FnOnce<(R, U)> for MappingStep<'t, R, T, F>
where F: Fn(U) -> T {
type Output = R;
extern "rust-call" fn call_once(self, args: (R, U)) -> R {
self.call(args)
}
}
impl<'t, R, T, U, F> FnMut<(R, U)> for MappingStep<'t, R, T, F>
where F: Fn(U) -> T {
extern "rust-call" fn call_mut(&mut self, args: (R, U)) -> R {
self.call(args)
}
}
impl<'t, R, T, U, F> Fn<(R, U)> for MappingStep<'t, R, T, F>
where F: Fn(U) -> T {
extern "rust-call" fn call(&self, (r, u): (R, U)) -> R {
(*self.step)(r, (self.f)(u))
}
}
pub struct Mapping<'t, T: 't, U, F: Fn(U) -> T + 't> {
f: &'t F,
phantom_f: PhantomData<fn(U) -> T>
}
impl<'t, R: 't, T: 't, U, F: Fn(U) -> T + 't> Transducer<'t, R, T, U>
for Mapping<'t, T, U, F> {
type Step = MappingStep<'t, R, T, F>;
fn apply<Step: Fn(R, T) -> R + 't>(&self, step: Step) -> MappingStep<'t, R, T, F> {
MappingStep {
step: Box::new(step),
f: self.f
}
}
}
impl<'f, T: 'f, U, F: Fn(U) -> T + 'f> Mapping<'f, T, U, F> {
pub fn new(f: &'f F) -> Mapping<'f, T, U, F> {
Mapping { f: f, phantom_f: PhantomData }
}
}
pub struct FilteringStep<'t, R, T, P: 't> {
step: Box<Fn(R, T) -> R + 't>,
p: &'t P
}
impl<'t, R, T, P> FnOnce<(R, T)> for FilteringStep<'t, R, T, P>
where P: Fn(&T) -> bool {
type Output = R;
extern "rust-call" fn call_once(self, args: (R, T)) -> R {
self.call(args)
}
}
impl<'t, R, T, P> FnMut<(R, T)> for FilteringStep<'t, R, T, P>
where P: Fn(&T) -> bool {
extern "rust-call" fn call_mut(&mut self, args: (R, T)) -> R {
self.call(args)
}
}
impl<'t, R, T, P> Fn<(R, T)> for FilteringStep<'t, R, T, P>
where P: Fn(&T) -> bool {
extern "rust-call" fn call(&self, (r, t): (R, T)) -> R {
if (self.p)(&t) {
(*self.step)(r, t)
} else {
r
}
}
}
pub struct Filtering<'p, T: 'p, P: Fn(&T) -> bool + 'p> {
p: &'p P,
phantom_p: PhantomData<fn(&T) -> bool>
}
impl<'p, R: 'p, T: 'p, P: Fn(&T) -> bool + 'p> Transducer<'p, R, T, T>
for Filtering<'p, T, P> {
type Step = FilteringStep<'p, R, T, P>;
fn apply<Step: Fn(R, T) -> R + 'p>(&self, step: Step) -> FilteringStep<'p, R, T, P> {
FilteringStep {
step: Box::new(step),
p: self.p
}
}
}
impl<'p, T, P: Fn(&T) -> bool + 'p> Filtering<'p, T, P> {
pub fn new(p: &'p P) -> Filtering<'p, T, P> {
Filtering { p: p, phantom_p: PhantomData }
}
}