use core::{
future::Future,
marker::PhantomData,
ops::ControlFlow,
pin::{pin, Pin},
ptr,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
use futures::FutureExt;
use pin_project::pin_project;
use crate::{higher_ranked_trait, higher_ranked_type, hkt::Marker};
// higher_ranked_trait! {
// pub type class Effective['lt, E] for<'a> {
// type Bound = &'a (&'lt (), T, E);
//
// type T: { Adapters<'a, Effect = E, T = T> + Sized + 'a }
// where {
// 'lt: 'a,
// T: 'a,
// E: Effect,
// };
//
// type HigherRanked: {} where {
// E: Effect,
// };
// }
// }
// fn do_thing<E: Effect>() -> ObjSafe<'static, i32, E> {
// E::ready(42).with(|x| {
// other::<E>(x).map(|x| x + 1).into()
// }).into()
// }
//
// fn other<E: Effect>(x: &i32) -> ObjSafe<'_, &i32, E> {
// E::ready(x).into()
// }
// pub mod Effective {
//
// }
//
pub trait Adapters<'lt>: Into<ObjSafe<'lt, Self::T, Self::Effect>> + 'lt {
type Effect: Effect;
type T: 'lt;
type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T>: Adapters<'a, Effect = Self::Effect, T = T>
where
'lt: 'a;
fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
F: FnOnce(Self::T) -> R,
'lt: 'a;
type AsCtxFor: HktFn<Self::Effect> + HktFnOwn<Self::Effect> + HktFnMut<Self::Effect>;
fn as_ctx_for<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, (Self::T, R), Self::Effect>
where
F: for<'b> FnOnce(
&'b mut Self::T,
PhantomData<&'b &'ctx ()>,
) -> (ObjSafe<'b, R, Self::Effect>, PhantomData<&'b &'ctx ()>);
fn then<'ctx, 'a, R: 'a, F: 'a>(
self,
f: F,
) -> <<Self::AsCtxFor as HktFnOwn<Self::Effect>>::T<Self::T, R, F, &'ctx ()> as ForLtFnOwn<
'a,
Self::T,
R,
F,
&'a (Self::T, R, F, &'ctx ()),
&'ctx (),
Self::Effect,
>>::T
where
F: for<'b> FnOnce(
Self::T,
PhantomData<&'b &'ctx ()>,
) -> ObjSafe<'b, R, Self::Effect>;
fn r#loop<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, R, Self::Effect>
where
F: for<'b> FnMut(&'b mut Self::T) -> ObjSafe<'b, ControlFlow<R>, Self::Effect>;
}
pub trait ForLt<'a, Output: 'a, B> {
type Effect: Effect;
type T: Adapters<'a, Effect = Self::Effect, T = Output>;
}
pub trait Hkt {
type Effect: Effect;
type T<Output, B>: for<'a> ForLt<'a, Output, &'a (Output, B), Effect = Self::Effect>;
}
pub trait ForLtFn<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect>
where
F: for<'b> FnOnce(
&'b mut Input,
PhantomData<&'b O>,
) -> (ObjSafe<'b, Output, E>, PhantomData<&'b O>),
{
type T: Adapters<'a, Effect = E, T = Output>;
}
pub trait HktFn<E: Effect> {
type T<Input, Output, F: for<'b> FnOnce(&'b mut Input, PhantomData<&'b B>) -> (ObjSafe<'b, Output, E>, PhantomData<&'b B>), B>: for<'a> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), B, E>;
}
impl<'b, T, Input: 'b, Output: 'b, ForBound, E: Effect> MutMapFnMut<'b, Input, Output, ForBound, E>
for T
where
T: FnMut(&'b mut Input) -> ObjSafe<'b, Output, E>,
{
fn call(&mut self, input: &'b mut Input) -> ObjSafe<'b, Output, E> {
self(input)
}
}
pub trait MutMapFnMut<'b, FIn: 'b, FOut: 'b, ForBound, E: Effect> {
fn call(&mut self, input: &'b mut FIn) -> ObjSafe<'b, FOut, E>;
}
pub trait ForLtFnMut<'a, FIn: 'a, FOut, Output: 'a, F: 'a, ForBound, E: Effect>
where
for<'b> F: MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), E>,
{
type T: Adapters<'a, Effect = E, T = Output>;
}
// pub trait ForLtFnMut<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect>
// where
// F: for<'b> FnMut(
// &'b mut Input,
// PhantomData<&'b O>,
// ) -> (ObjSafe<'b, Output, E>, PhantomData<&'b O>),
// {
// type T: Adapters<'a, Effect = E, T = Output>;
// }
pub trait HktFnMut<E: Effect> {
type T<FIn, FOut, Output, F: for<'b> MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), E>, ForBound>: for<'a> ForLtFnMut<'a, FIn, FOut, Output, F, &'a (FIn, Output, F, ForBound), E>;
}
// pub trait HktFnMut<E: Effect> {
// type T<Input, Output, F: for<'b> FnMut(&'b mut Input, PhantomData<&'b B>) -> (ObjSafe<'b, Output, E>, PhantomData<&'b B>), B>: for<'a> ForLtFnMut<'a, Input, Output, F, &'a (Input, Output, F, B), B, E>;
// }
pub trait ForLtFnOwn<'a, Input: 'a, Output: 'a, F: 'a, B, O, E: Effect>
where
F: for<'b> FnOnce(Input, PhantomData<&'b O>) -> ObjSafe<'b, Output, E>,
{
type T: Adapters<'a, Effect = E, T = Output>;
}
pub trait HktFnOwn<E: Effect> {
type T<Input, Output, F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, E>, B>: for<'a> ForLtFnOwn<'a, Input, Output, F, &'a (Input, Output, F, B),B, E>;
}
// pub trait ForLtFn<'a, E: Effect> {
// type T<Input: 'a, Output: 'a, F: 'a + for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, E>>: Adapters<'a, Effect = E, T = Output>;
// }
//
// pub trait HktFn<E: Effect>: for<'a> ForLtFn<'a, E> {}
/// Trait for effects.
pub trait Effect: Sized + Send + Sync + 'static {
type ObjSafe: Hkt<Effect = Self>;
type Ready: Hkt<Effect = Self>;
fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T;
type With: HktFn<Self>;
fn with<'ctx, 'a, T: 'a, R: 'a, F: 'a>(
x: T,
f: F,
) -> <<Self::With as HktFn<Self>>::T<T, R, F, &'ctx ()> as ForLtFn<
'a,
T,
R,
F,
&'a (T, R, F, &'ctx ()),
&'ctx (),
Self,
>>::T
where
F: for<'b> FnOnce(
&'b mut T,
PhantomData<&'b &'ctx ()>,
) -> (ObjSafe<'b, R, Self>, PhantomData<&'b &'ctx ()>);
fn join<'a, T: 'a>(tuple: T) -> ObjSafe<'a, T::Output, Self>
where
T: Joinable<'a, Self>,
{
T::join(tuple)
}
fn try_join<'a, T: 'a>(tuple: T) -> ObjSafe<'a, Result<T::Output, T::Error>, Self>
where
T: TryJoinable<'a, Self>,
{
T::try_join(tuple)
}
}
pub trait Joinable<'a, E: Effect>: Sized {
type Output;
fn join(tuple: Self) -> ObjSafe<'a, Self::Output, E>;
}
pub struct Join<T, B>(pub T, pub Marker<B>);
impl<'a, E: Effect, T0> Joinable<'a, E> for Join<(ObjSafe<'a, T0, E>,), (T0,)> {
fn join(Join((a,), _): Self) -> ObjSafe<'a, (T0,), E> {
a.map(|x| (x,)).into()
}
type Output = (T0,);
}
impl<'a, E: Effect, T0, T1> Joinable<'a, E>
for Join<(ObjSafe<'a, T0, E>, ObjSafe<'a, T1, E>), (T0, T1)>
{
fn join(Join((a, b), _): Self) -> ObjSafe<'a, (T0, T1), E> {
a.then(|a, _| b.map(|b| (a, b)).into()).into()
}
type Output = (T0, T1);
}
pub trait TryJoinable<'a, E: Effect>: Sized {
type Output;
type Error;
fn try_join(tuple: Self) -> ObjSafe<'a, Result<Self::Output, Self::Error>, E>;
}
impl<'a, E: Effect, Err, T0, T1> TryJoinable<'a, E>
for Join<
(
ObjSafe<'a, Result<T0, Err>, E>,
ObjSafe<'a, Result<T1, Err>, E>,
),
(Err, T0, T1),
>
{
fn try_join(Join((a, b), _): Self) -> ObjSafe<'a, Result<(T0, T1), Err>, E> {
a.then(|a, _| {
match a {
Ok(a) => b
.map(|b| match b {
Ok(b) => Ok((a, b)),
Err(err) => Err(err),
})
.into(),
Err(err) => E::ready(Err(err)).into(),
}
// b.map(|b| (a, b)).into()
})
.into()
}
type Output = (T0, T1);
type Error = Err;
}
pub type ObjSafe<'a, T, E, B = ()> =
<<<E as Effect>::ObjSafe as Hkt>::T<T, B> as ForLt<'a, T, &'a (T, B)>>::T;
pub enum Blocking {}
pub enum ValueHkt {}
impl Hkt for ValueHkt {
type Effect = Blocking;
type T<Output, B> = ValueHrt<Output, B>;
}
pub struct ValueHrt<T, B>(Marker<(T, B)>);
impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for ValueHrt<T, B> {
type Effect = Blocking;
type T = Value<T>;
}
pub enum WithHkt {}
impl HktFnOwn<Blocking> for WithHkt {
type T<
Input,
Output,
F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, Blocking>,
B,
> = WithHkt;
}
impl<'a, Input, Output, F, B>
ForLtFnOwn<'a, Input, Output, F, &'a (Input, Output, F, B), B, Blocking> for WithHkt
where
F: for<'b> FnOnce(Input, PhantomData<&'b B>) -> ObjSafe<'b, Output, Blocking>,
{
type T = Value<Output>;
}
impl HktFn<Blocking> for WithHkt {
type T<
Input,
Output,
F: for<'b> FnOnce(
&'b mut Input,
PhantomData<&'b B>,
) -> (ObjSafe<'b, Output, Blocking>, PhantomData<&'b B>),
B,
> = WithHkt;
}
impl<'a, Input, Output, F, B> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), B, Blocking>
for WithHkt
where
F: for<'b> FnOnce(
&'b mut Input,
PhantomData<&'b B>,
) -> (ObjSafe<'b, Output, Blocking>, PhantomData<&'b B>),
{
type T = Value<Output>;
}
impl HktFnMut<Blocking> for WithHkt {
type T<
FIn,
FOut,
Output,
F: for<'b> MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), Blocking>,
ForBound,
> = WithHkt;
}
impl<'a, FIn, FOut, Output, F, B>
ForLtFnMut<'a, FIn, FOut, Output, F, &'a (FIn, Output, F, B), Blocking> for WithHkt
where
for<'b> F: MutMapFnMut<'b, FIn, FOut, &'b (FIn, FOut), Blocking>,
{
type T = Value<Output>;
}
impl Effect for Blocking {
type ObjSafe = ValueHkt;
type Ready = ValueHkt;
fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T {
Value(x)
}
type With = WithHkt;
#[inline(always)]
fn with<'ctx, 'a, T: 'a, R: 'a, F: 'a>(
x: T,
f: F,
) -> <<Self::With as HktFn<Self>>::T<T, R, F, &'ctx ()> as ForLtFn<
'a,
T,
R,
F,
&'a (T, R, F, &'ctx ()),
&'ctx (),
Self,
>>::T
where
F: for<'b> FnOnce(
&'b mut T,
PhantomData<&'b &'ctx ()>,
) -> (ObjSafe<'b, R, Self>, PhantomData<&'b &'ctx ()>),
{
let mut ctx = x;
f(&mut ctx, PhantomData).0
}
}
pub struct Value<T>(pub T);
impl<'b, U: 'b> Adapters<'b> for Value<U> {
type Effect = Blocking;
type T = U;
type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = Value<T> where 'b: 'a;
fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
F: FnOnce(Self::T) -> R,
'b: 'a,
{
Value(f(self.0))
}
type AsCtxFor = WithHkt;
#[inline(always)]
fn as_ctx_for<'ctx, 'a, R: 'a, F: 'a>(self, f: F) -> ObjSafe<'a, (Self::T, R), Blocking>
where
F: for<'c> FnOnce(
&'c mut Self::T,
PhantomData<&'c &'ctx ()>,
) -> (ObjSafe<'c, R, Self::Effect>, PhantomData<&'c &'ctx ()>),
{
let mut ctx = self.0;
let value = f(&mut ctx, PhantomData).0 .0;
Value((ctx, value))
}
fn then<'ctx, 'a, R: 'a, F: 'a>(
self,
f: F,
) -> <<Self::AsCtxFor as HktFnOwn<Self::Effect>>::T<Self::T, R, F, &'ctx ()> as ForLtFnOwn<
'a,
Self::T,
R,
F,
&'a (Self::T, R, F, &'ctx ()),
&'ctx (),
Self::Effect,
>>::T
where
F: for<'c> FnOnce(
Self::T,
PhantomData<&'c &'ctx ()>,
) -> ObjSafe<'c, R, Self::Effect>{
f(self.0, PhantomData)
}
#[inline(always)]
fn r#loop<'ctx, 'a, R: 'a, F: 'a>(mut self, mut f: F) -> ObjSafe<'a, R, Blocking>
where
F: for<'c> FnMut(&'c mut Self::T) -> ObjSafe<'c, ControlFlow<R>, Self::Effect>,
{
loop {
if let ControlFlow::Break(value) = f(&mut self.0).0 {
return Value(value);
}
}
}
}
/*
pub enum Async {}
impl Effect for Async {
type ObjSafe = BoxedFutureHkt;
type Ready = AsyncValueHkt;
fn ready<'a, T: 'a>(x: T) -> <<Self::Ready as Hkt>::T<T, ()> as ForLt<'a, T, &'a (T, ())>>::T {
AsyncValue(x)
}
type With = AsyncWithHkt;
fn with<'a, T: 'a, R: 'a, F: 'a>(
x: T,
f: F,
) -> <<Self::With as HktFn<Self>>::T<T, R, F, ()> as ForLtFn<
'a,
T,
R,
F,
&'a (T, R, F, ()),
Self,
>>::T
where
F: FnOnce(&mut T) -> ObjSafe<'_, R, Self>,
{
BoxedFuture(Box::pin(async move {
let mut x = x;
let fut = f(&mut x).0;
fut.await
}))
}
}
pub enum BoxedFutureHkt {}
impl Hkt for BoxedFutureHkt {
type Effect = Async;
type T<Output, B> = BoxedFutureHrt<Output, B>;
}
pub struct BoxedFutureHrt<Output, B>(Marker<(Output, B)>);
impl<'a, Output, B> ForLt<'a, Output, &'a (Output, B)> for BoxedFutureHrt<Output, B> {
type Effect = Async;
type T = BoxedFuture<'a, Output>;
}
pub enum AsyncValueHkt {}
impl Hkt for AsyncValueHkt {
type Effect = Async;
type T<Output, B> = AsyncValue<Output>;
}
pub enum AsyncWithHkt {}
impl HktFn<Async> for AsyncWithHkt {
type T<Input, Output, F: for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>, B> =
AsyncWithHkt;
}
impl<'a, Input, Output, F, B> ForLtFn<'a, Input, Output, F, &'a (Input, Output, F, B), Async>
for AsyncWithHkt
where
F: for<'b> FnOnce(&'b mut Input) -> ObjSafe<'b, Output, Async>,
{
type T = BoxedFuture<'a, Output>;
}
pub struct AsyncValue<T>(pub T);
impl<'a, T, B> ForLt<'a, T, &'a (T, B)> for AsyncValue<T> {
type Effect = Async;
type T = AsyncValue<T>;
}
pub struct BoxedFuture<'a, T: 'a>(pub Pin<Box<dyn Future<Output = T> + 'a>>);
impl<'b, U: 'b> Adapters<'b> for AsyncValue<U> {
type Effect = Async;
type T = U;
type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncValue<T> where 'b: 'a;
fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
F: FnOnce(Self::T) -> R,
'b: 'a,
{
AsyncValue(f(self.0))
}
}
impl<'b, U: 'b> Adapters<'b> for BoxedFuture<'b, U> {
type Effect = Async;
type T = U;
type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncMap<Self, F> where 'b: 'a;
fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
F: FnOnce(Self::T) -> R,
'b: 'a,
{
AsyncMap {
map: futures::FutureExt::map(self, f),
}
}
}
#[pin_project]
pub struct AsyncMap<Fut, F> {
#[pin]
map: futures::future::Map<Fut, F>,
}
impl<'b, U: 'b, Fut0: 'b, F0: 'b> Adapters<'b> for AsyncMap<Fut0, F0>
where
Fut0: Future,
F0: FnOnce(Fut0::Output) -> U,
{
type Effect = Async;
type T = U;
type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncMap<Self, F> where 'b: 'a;
fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
F: FnOnce(Self::T) -> R,
'b: 'a,
{
AsyncMap {
map: futures::FutureExt::map(self, f),
}
}
}
impl<T, Fut, F> Future for AsyncMap<Fut, F>
where
Fut: Future,
F: FnOnce(Fut::Output) -> T,
{
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
this.map.poll(cx)
}
}
impl<'a, T> Future for BoxedFuture<'a, T> {
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.0.poll_unpin(cx)
}
}
impl<'a, T, Fut: 'a, F: 'a> From<AsyncMap<Fut, F>> for BoxedFuture<'a, T>
where
Fut: Future,
F: FnOnce(Fut::Output) -> T,
{
fn from(value: AsyncMap<Fut, F>) -> Self {
BoxedFuture(Box::pin(value.map))
}
}
impl<'a, T: 'a> From<AsyncValue<T>> for BoxedFuture<'a, T> {
fn from(value: AsyncValue<T>) -> Self {
BoxedFuture(Box::pin(futures::future::ready(value.0)))
}
}
*/
/*
pub trait ReadyValue: core::future::Future {
fn value(self) -> Self::Output;
}
impl<T: Send> ReadyValue for core::future::Ready<T> {
fn value(self) -> Self::Output {
Spin::block_on(self)
}
}
pub trait BlockOn: 'static {
fn block_on<F>(future: F) -> F::Output
where
F: core::future::Future + Send,
<F as core::future::Future>::Output: Send;
}
/// [`BlockOn`] implementer that just spins on the future.
///
/// This is useful for futures that are alwayd ready.
pub enum Spin {}
impl BlockOn for Spin {
#[inline(always)]
fn block_on<F>(future: F) -> F::Output
where
F: core::future::Future + Send,
{
let waker = noop();
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
if let Poll::Ready(value) = future.as_mut().poll(&mut context) {
return value;
}
}
}
}
#[inline]
pub fn noop() -> Waker {
const VTABLE: &RawWakerVTable = &RawWakerVTable::new(
// Cloning just returns a new no-op raw waker
|_| RAW,
// `wake` does nothing
|_| {},
// `wake_by_ref` does nothing
|_| {},
// Dropping does nothing as we don't allocate anything
|_| {},
);
const RAW: RawWaker = RawWaker::new(ptr::null(), VTABLE);
unsafe { Waker::from_raw(RAW) }
}
// pub struct Ready<Output> {
// pub value: Option<Output>,
// }
//
// impl<Output> Ready<Output> {
// pub fn into_inner(self) -> Output {
// self.value.expect("`into_inner` called after completion")
// }
// }
//
// impl<Output> Unpin for Ready<Output> {}
//
// impl<Output> core::future::Future for Ready<Output> {
// type Output = Output;
//
// fn poll(mut self: core::pin::Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
// Poll::Ready(self.value.take().expect("`Ready` polled after completion"))
// }
// }
higher_ranked_type! {
impl SendFuture {
impl['a, Output] type T['a, Output] for core::future::Ready<Output> =
core::future::Ready<Output>
where {
Output: Send
};
impl['a, Output] type HigherRanked['a, Output] for core::future::Ready<Output> =
core::future::Ready<Output>
where {
Output: Send
};
}
}
impl<B: BlockOn> Effect for Blocking<B> {
type Future<T: Send> = core::future::Ready<T>;
#[inline(always)]
fn wrap<'a, F>(future: F) -> SendFuture::T<'a, F::Output, Self::Future<F::Output>>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
{
core::future::ready(B::block_on(future))
}
#[inline(always)]
fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, T, Self::Future<T>> {
core::future::ready(value)
}
#[inline(always)]
fn map<'a, T, U, F>(
future: SendFuture::T<'a, T, Self::Future<T>>,
func: F,
) -> SendFuture::T<'a, U, Self::Future<U>>
where
T: Send,
U: Send,
F: FnOnce(T) -> U + Send + 'a,
{
let value = B::block_on(future);
core::future::ready(func(value))
}
}
mod sealed {
pub enum BoxedFuture<'lt, Output> {
Box(core::pin::Pin<Box<dyn core::future::Future<Output = Output> + Send + 'lt>>),
Ready(core::future::Ready<Output>),
}
impl<'lt, Output> core::future::Future for BoxedFuture<'lt, Output> {
type Output = Output;
fn poll(
mut self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
match &mut *self {
BoxedFuture::Box(future) => future.as_mut().poll(cx),
BoxedFuture::Ready(future) => core::pin::Pin::new(future).poll(cx),
}
}
}
}
#[cfg(feature = "alloc")]
pub struct BoxedFutureHrt<Output>(Marker<Output>);
#[cfg(feature = "alloc")]
higher_ranked_type! {
impl SendFuture {
impl['a, Output] type T['a, Output] for BoxedFutureHrt<Output> =
sealed::BoxedFuture<'a, Output>
where {
Output: Send
};
impl['a, Output] type HigherRanked['a, Output] for sealed::BoxedFuture<'a, Output> =
BoxedFutureHrt<Output>
where {
Output: Send
};
}
}
#[cfg(feature = "alloc")]
pub enum Async {}
#[cfg(feature = "alloc")]
impl Effect for Async {
type Future<T: Send> = BoxedFutureHrt<T>;
fn wrap<'a, F>(future: F) -> SendFuture::T<'a, F::Output, Self::Future<F::Output>>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
{
sealed::BoxedFuture::Box(Box::pin(future))
}
fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, T, Self::Future<T>> {
sealed::BoxedFuture::Ready(core::future::ready(value))
}
fn map<'a, T, U, F>(
future: SendFuture::T<'a, T, Self::Future<T>>,
func: F,
) -> SendFuture::T<'a, U, Self::Future<U>>
where
T: Send,
U: Send,
F: FnOnce(T) -> U + Send + 'a,
{
match future {
sealed::BoxedFuture::Box(future) => Self::wrap(async { func(future.await) }),
sealed::BoxedFuture::Ready(future) => {
let value = Spin::block_on(future);
Self::ready(func(value))
}
}
}
fn wrap_boxed<'a, F>(
future: core::pin::Pin<Box<F>>,
) -> SendFuture::T<'a, F::Output, Self::Future<F::Output>>
where
F: core::future::Future + Send + 'a,
<F as core::future::Future>::Output: Send,
{
sealed::BoxedFuture::Box(future)
}
}
*/