use core::marker::PhantomData;
use crate::{
mode::Mode,
task::{
Task,
TaskOutput,
},
};
struct MapResult<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 MapResult<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, BO> + 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.map_result(self.prev.go(mode, input), move |mode, output| {
self.next.go(mode, output)
})
}
}
#[inline(always)]
pub const fn map_result<'src, I, E, BI, BO>(
a: impl Task<'src, I, Result<BI, E>>,
b: impl Task<'src, BI, BO> + Send + 'src,
) -> impl Task<'src, I, Result<BO, E>>
where
E: Send + 'src,
BI: Send + 'src,
BO: Send + 'src,
{
MapResult {
prev: a,
next: b,
_phantom: PhantomData,
}
}
struct MapOption<A, B, IO> {
prev: A,
next: B,
_phantom: PhantomData<IO>,
}
impl<'src, AI, BI, BO, A, B> Task<'src, AI, Option<BO>> for MapOption<A, B, BI>
where
BI: Send + 'src,
BO: Send + 'src,
A: Task<'src, AI, Option<BI>>,
B: Task<'src, BI, 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.map_option(self.prev.go(mode, input), move |mode, output| {
self.next.go(mode, output)
})
}
}
#[inline(always)]
pub const fn map_option<'src, I, BI, BO>(
a: impl Task<'src, I, Option<BI>>,
b: impl Task<'src, BI, BO> + Send + 'src,
) -> impl Task<'src, I, Option<BO>>
where
BI: Send + 'src,
BO: Send + 'src,
{
MapOption {
prev: a,
next: b,
_phantom: PhantomData,
}
}
struct MapIterator<A, B, IO> {
prev: A,
next: B,
_phantom: PhantomData<IO>,
}
impl<'src, I, O, IO, BO, IBO, A, B> Task<'src, I, IBO> for MapIterator<A, B, IO>
where
IO: Iterator<Item = O> + Send + 'src,
BO: Send + 'src,
IBO: Iterator<Item = BO> + Send + 'src,
A: Task<'src, I, IO>,
B: Task<'src, O, BO> + Clone + Send + 'src,
{
go_impl!('src, I, IBO);
#[inline]
fn go<M>(self, mode: &'src M, input: I) -> TaskOutput<'src, M, IBO>
where
Self: Sized,
M: Mode<'src> + Send + Sync,
{
unimplemented!("I probably need to have a Self::StreamOutput type - because Iterator is a trait we would have to constraint all the go_whatever sites to be the same concrete type")
}
}
#[inline(always)]
pub const fn map_iterator<'src, I, O, IO, BO, IBO>(
a: impl Task<'src, I, IO>,
b: impl Task<'src, O, BO> + Clone + Send + 'src,
) -> impl Task<'src, I, IBO>
where
IO: Iterator<Item = O> + Send + 'src,
BO: Send + 'src,
IBO: Iterator<Item = BO> + Send + 'src,
{
MapIterator {
prev: a,
next: b,
_phantom: PhantomData,
}
}