dewit 0.0.1

Define scheduling and execution of code separately from data flow
Documentation
use core::marker::PhantomData;

use crate::{
    mode::Mode,
    task::{
        Task,
        TaskOutput,
    },
};

#[repr(transparent)]
struct Cpu<I, T, F> {
    f: F,
    _phantom: PhantomData<(I, T)>,
}

impl<'src, I, O, F> Task<'src, I, O> for Cpu<I, O, F>
where
    I: Send + 'src,
    O: Send + 'src,
    F: FnOnce(I) -> O + Send + 'src,
{
    go_impl!('src, I, O);

    #[inline]
    fn go<M>(self, mode: &M, input: I) -> TaskOutput<'src, M, O>
    where
        Self: Sized,
        M: Mode<'src>,
    {
        mode.spawn_cpu(move || (self.f)(input))
    }
}

/// Treat the wrapped closure as performing CPU-bound work, for which a [`Mode`]
/// can implement scheduling behavior.
#[inline(always)]
pub const fn cpu<'src, I, O>(f: impl FnOnce(I) -> O + Send + 'src) -> impl Task<'src, I, O>
where
    I: Send + 'src,
    O: Send + 'src,
{
    Cpu {
        f,
        _phantom: PhantomData,
    }
}