use core::marker::PhantomData;
use crate::{
mode::Mode,
task::{
Task,
TaskOutput,
},
};
struct AndThenResult<A, B, E, IO> {
prev: A,
next: B,
_phantom: PhantomData<(E, IO)>,
}
impl<'src, AI, E, BI, BO, A, B> Task<'src, AI, Result<BO, E>> for AndThenResult<A, B, E, BI>
where
E: Send + 'src,
BI: Send + 'src,
BO: Send + 'src,
A: Task<'src, AI, Result<BI, E>>,
B: Task<'src, BI, Result<BO, E>> + Send + 'src,
{
go_impl!('src, AI, Result<BO, E>);
#[inline]
fn go<M>(self, mode: &'src M, input: AI) -> TaskOutput<'src, M, Result<BO, E>>
where
Self: Sized,
M: Mode<'src> + Send + Sync,
{
mode.and_then_result(self.prev.go(mode, input), move |mode, output| {
self.next.go(mode, output)
})
}
}
#[inline(always)]
pub const fn and_then_result<'src, I, E, BI, BO>(
a: impl Task<'src, I, Result<BI, E>>,
b: impl Task<'src, BI, Result<BO, E>> + Send + 'src,
) -> impl Task<'src, I, Result<BO, E>>
where
E: Send + 'src,
BI: Send + 'src,
BO: Send + 'src,
{
AndThenResult {
prev: a,
next: b,
_phantom: PhantomData,
}
}
struct AndThenOption<A, B, IO> {
prev: A,
next: B,
_phantom: PhantomData<IO>,
}
impl<'src, AI, BI, BO, A, B> Task<'src, AI, Option<BO>> for AndThenOption<A, B, BI>
where
BI: Send + 'src,
BO: Send + 'src,
A: Task<'src, AI, Option<BI>>,
B: Task<'src, BI, Option<BO>> + Send + 'src,
{
go_impl!('src, AI, Option<BO>);
#[inline]
fn go<M>(self, mode: &'src M, input: AI) -> TaskOutput<'src, M, Option<BO>>
where
Self: Sized,
M: Mode<'src> + Send + Sync,
{
mode.and_then_option(self.prev.go(mode, input), move |mode, output| {
self.next.go(mode, output)
})
}
}
#[inline(always)]
pub const fn and_then_option<'src, I, BI, BO>(
a: impl Task<'src, I, Option<BI>>,
b: impl Task<'src, BI, Option<BO>> + Send + 'src,
) -> impl Task<'src, I, Option<BO>>
where
BI: Send + 'src,
BO: Send + 'src,
{
AndThenOption {
prev: a,
next: b,
_phantom: PhantomData,
}
}