use crate::cons::{Cons, ConsCell, Nil};
pub trait ForEachFn<Input> {
fn run(input: Input);
}
pub trait ForEachFns<C: ConsCell> {
fn for_each(c: C);
}
impl<C: Cons, F> ForEachFns<C> for F
where
Self: ForEachFn<C::Head>,
Self: ForEachFns<C::Tail>,
{
#[inline(always)]
fn for_each(c: C) {
let (head, tail) = c.split();
<Self as ForEachFn<C::Head>>::run(head);
<Self as ForEachFns<C::Tail>>::for_each(tail);
}
}
impl<NilSeed, F> ForEachFns<Nil<NilSeed>> for F {
fn for_each(_c: Nil<NilSeed>) {}
}
pub trait ForEach: ConsCell {
#[inline(always)]
fn for_each<F: ForEachFns<Self>>(self) {
F::for_each(self);
}
}
impl<C: ConsCell> ForEach for C {}
#[cfg(test)]
mod tests {
use super::*;
use crate::cons::types::hcons::HNil;
use std::fmt::Debug;
struct PrintForEach {}
impl<T: Debug> ForEachFn<T> for PrintForEach {
fn run(input: T) {
dbg!(input);
}
}
#[test]
fn it_works() {
let x = HNil::new().extend(1u8).extend(2u16);
x.for_each::<PrintForEach>();
}
}