| -rw-r--r-- | src/any.rs | 70 | ||||
| -rw-r--r-- | src/effect.rs | 234 | ||||
| -rw-r--r-- | src/effect/async.rs | 492 | ||||
| -rw-r--r-- | src/effect/blocking.rs | 269 | ||||
| -rw-r--r-- | src/effect/blocking/spin.rs | 46 | ||||
| -rw-r--r-- | src/hkt.rs | 27 |
6 files changed, 933 insertions, 205 deletions
@@ -3,7 +3,7 @@ //! The `AnyTrait` trait provides dynamic upcasting to trait objects. pub mod indirect; -mod static_wrapper; +// mod static_wrapper; mod type_name_id; use crate::{ @@ -12,7 +12,7 @@ use crate::{ }; use core::marker::PhantomData; -pub use static_wrapper::*; +// pub use static_wrapper::*; pub use type_name_id::*; #[cfg(all(feature = "alloc", not(feature = "std")))] @@ -46,44 +46,50 @@ higher_ranked_type! { where { T: ?Sized + TypeName::LowerType<'a, 'ctx> }; - } -} - -pub struct MutHrt<T: ?Sized>(Marker<T>); - -higher_ranked_type! { - impl TypeName { - impl['a, 'ctx, T] type T['a, 'ctx] for MutHrt<T> = - &'a mut TypeName::T<'a, 'ctx, T> - where { - T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>, - TypeName::T<'a, 'ctx, T>: 'a - }; - impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for &'a mut T = - MutHrt<TypeName::HigherRanked<'a, 'ctx, T>> + impl['a, 'ctx, T] type HigherRankedAll['a, 'ctx] for &'a T = + RefHrt<TypeName::HigherRankedAll<'a, 'ctx, T>> where { T: ?Sized + TypeName::LowerType<'a, 'ctx> }; } } -#[cfg(feature = "alloc")] -higher_ranked_type! { - impl TypeName { - impl['a, 'ctx, T] type T['a, 'ctx] for Box<T> = - Box<TypeName::T<'a, 'ctx, T>> - where { - T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>, - }; +pub struct MutHrt<T: ?Sized>(Marker<T>); - impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for Box<T> = - Box<TypeName::HigherRanked<'a, 'ctx, T>> - where { - T: ?Sized + TypeName::LowerType<'a, 'ctx> - }; - } -} +// higher_ranked_type! { +// impl TypeName { +// impl['a, 'ctx, T] type T['a, 'ctx] for MutHrt<T> = +// &'a mut TypeName::T<'a, 'ctx, T> +// where { +// T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>, +// TypeName::T<'a, 'ctx, T>: 'a +// }; +// +// impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for &'a mut T = +// MutHrt<TypeName::HigherRanked<'a, 'ctx, T>> +// where { +// T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>> +// }; +// } +// } + +// #[cfg(feature = "alloc")] +// higher_ranked_type! { +// impl TypeName { +// impl['a, 'ctx, T] type T['a, 'ctx] for Box<T> = +// Box<TypeName::T<'a, 'ctx, T>> +// where { +// T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>, +// }; +// +// impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for Box<T> = +// Box<TypeName::HigherRanked<'a, 'ctx, T>> +// where { +// T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>> +// }; +// } +// } /// Dynamic trait lookup. /// diff --git a/src/effect.rs b/src/effect.rs index 84b275b..e8891ad 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -1,7 +1,10 @@ +pub mod r#async; pub mod blocking; use core::{future::Future, ops::ControlFlow}; +use crate::{higher_ranked_trait, higher_ranked_type}; + // Goal: code using the module shouldn't care if the underlying environment is async or not. // That is the API should allow yielding without forcing it. // @@ -38,115 +41,163 @@ use core::{future::Future, ops::ControlFlow}; pub trait Effect: Join<Effect = Self> + TryJoin<Effect = Self> + Send + Sync + Sized + 'static { - type Erased<T>: Effective<Output = T, Effect = Self>; + type Erased<T: Send + Sync>: ErasedHrt<T, Self>; - type Ready<T>: Effective<Output = T, Effect = Self>; + type Ready<'a, T: Send + Sync + 'a>: Effective<'a, Output = T, Effect = Self>; - fn ready<T>(value: T) -> Self::Ready<T>; + fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T>; - type FromFuture<F>: Effective<Output = F::Output, Effect = Self> + type FromFuture<'a, F: Send + Sync + 'a>: Effective<'a, Output = F::Output, Effect = Self> where - F: Future; + F: Future, + F::Output: Send + Sync + 'a; - fn from_future<F>() -> Self::FromFuture<F> + fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> where - F: Future; + F: Future, + F::Output: Send + Sync + 'a; } -pub trait EffectiveForLt<'a, Output: 'a, E: Effect, Bound> { - type T: Effective<Output = Output, Effect = E>; +pub trait ErasedForLt<'a, T: Send + Sync + 'a, E: Effect, Bound: 'a> { + type T: Effective<'a, Output = T, Effect = E>; } -pub trait EffectiveHrt<Output, E: Effect>: for<'a> EffectiveForLt<'a, Output, E, &'a Output> {} +pub trait ErasedHrt<T: Send + Sync, E: Effect>: for<'a> ErasedForLt<'a, T, E, &'a T> {} + +impl<T: Send + Sync, E: Effect, U> ErasedHrt<T, E> for U where + U: for<'a> ErasedForLt<'a, T, E, &'a T> +{ +} -pub type EffectiveT<'a, V, Output, E> = <V as EffectiveForLt<'a, Output, E, &'a Output>>::T; +pub type ErasedEffective<'lt, Output, E> = + <<E as Effect>::Erased<Output> as ErasedForLt<'lt, Output, E, &'lt Output>>::T; + +pub trait Effective<'lt>: Send + Sync + 'lt { + fn into_erased(self) -> ErasedEffective<'lt, Self::Output, Self::Effect>; -pub trait Effective: Into<<Self::Effect as Effect>::Erased<Self::Output>> { /// The effect the effective belongs to. type Effect: Effect; /// The type of the effective's output value. - type Output; + type Output: Send + Sync + 'lt; /// Future that resolves to the same value as the effective. - type IntoFuture: Future<Output = Self::Output>; + type IntoFuture: Send + Sync + Future<Output = Self::Output>; /// Convert the effective into a general future for use in async. fn into_future(self) -> Self::IntoFuture; - /// Effective performing a loop. - type Loop<T, V, F>: Effective<Output = (Self::Output, T), Effect = Self::Effect> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>; - - /// Perform a loop with the effective value as context. - /// - /// When the callback returns break then the loop will end and the effective - /// will resolve to the break value and the context. - fn r#loop<T, V, F>(self, cb: F) -> Self::Loop<T, V, F> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>; - - type Map<T, F>: Effective<Output = T, Effect = Self::Effect> + // /// Effective performing a loop. + // type Loop<T, V, F>: Effective<Output = (Self::Output, T), Effect = Self::Effect> + // where + // F: MutFnOnceHrt<Self::Output, T, Self::Effect>; + // + // /// Perform a loop with the effective value as context. + // /// + // /// When the callback returns break then the loop will end and the effective + // /// will resolve to the break value and the context. + // fn r#loop<T, V, F>(self, cb: F) -> Self::Loop<T, V, F> + // where + // F: MutFnOnceHrt<Self::Output, T, Self::Effect>; + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + 'a, + Output = T, + Effect = Self::Effect, + > where - F: FnOnce(Self::Output) -> T; + F: FnOnce(Self::Output) -> T, + 'lt: 'a; - fn map<T, F>(self, cb: F) -> Self::Map<T, F> + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> where - F: FnOnce(Self::Output) -> T; + F: FnOnce(Self::Output) -> T, + 'lt: 'a; - type Then<T, V, F>: Effective<Output = T, Effect = Self::Effect> + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + 'a, + Output = T, + Effect = Self::Effect, + > where F: FnOnce(Self::Output) -> V, - V: Effective<Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>; - fn then<T, V, F>(self, cb: F) -> Self::Then<T, V, F> + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, - V: Effective<Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>; - type AsCtx<T, V, F>: Effective<Output = (Self::Output, T), Effect = Self::Effect> + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + 'a, + Output = (Self::Output, T), + Effect = Self::Effect, + > where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>; + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; - fn as_ctx<T, V, F>(self, cb: F) -> Self::AsCtx<T, V, F> + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>; + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; } pub trait Join { type Effect: Effect; - type Two<T0, T1>: Effective<Output = (T0::Output, T1::Output), Effect = Self::Effect> + type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>: Effective< + 'a, + Output = (T0::Output, T1::Output), + Effect = Self::Effect, + > where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>; + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>; - type Three<T0, T1, T2>: Effective< + type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>: Effective< + 'a, Output = (T0::Output, T1::Output, T2::Output), Effect = Self::Effect, > where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>; - - fn two<T0, T1, F0, F1>(cb: (F0, F1)) -> Self::Two<T0, T1> + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, + T2: Effective<'a, Effect = Self::Effect>; + + fn two< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, T0, T1> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, F0: FnOnce() -> T0, F1: FnOnce() -> T1; - fn three<T0, T1, T2, F0, F1, F2>(effectives: (F0, F1, F2)) -> Self::Three<T0, T1, T2> + fn three< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( + effectives: (F0, F1, F2), + ) -> Self::Three<'a, T0, T1, T2> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>, + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, + T2: Effective<'a, Effect = Self::Effect>, F0: FnOnce() -> T0, F1: FnOnce() -> T1, F2: FnOnce() -> T2; @@ -155,35 +206,58 @@ pub trait Join { pub trait TryJoin { type Effect: Effect; - type Two<Err, V0, V1, T0, T1>: Effective<Output = Result<(T0, T1), Err>, Effect = Self::Effect> + type Two<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>: Effective<'a, Output = Result<(T0, T1), Err>, Effect = Self::Effect> where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>; + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>; - type Three<Err, V0, V1, V2, T0, T1, T2>: Effective< + type Three<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, V2: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>: Effective<'a, Output = Result<(T0, T1, T2), Err>, Effect = Self::Effect, > where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>; - - fn two<Err, T0, T1, V0, V1, F0, F1>(cb: (F0, F1)) -> Self::Two<Err, V0, V1, T0, T1> + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>; + + fn two< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, Err, V0, V1, T0, T1> where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1; - - fn three<Err, T0, T1, T2, V0, V1, V2, F0, F1, F2>( + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1; + + fn three< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + V2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( cb: (F0, F1, F2), - ) -> Self::Three<Err, V0, V1, V2, T0, T1, T2> + ) -> Self::Three<'a, Err, V0, V1, V2, T0, T1, T2> where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - F2: FnOnce() -> T2; + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1, + F2: FnOnce() -> V2; } diff --git a/src/effect/async.rs b/src/effect/async.rs new file mode 100644 index 0000000..84aacee --- /dev/null +++ b/src/effect/async.rs @@ -0,0 +1,492 @@ +use core::pin::Pin; + +use core::future::Future; + +use futures::FutureExt as _; +use pin_project::pin_project; + +use crate::hkt::Marker; + +use super::{Effect, Effective, ErasedForLt, Join, TryJoin}; + +pub enum Async {} + +pub struct ErasedHrt<T>(Marker<T>); + +#[pin_project(project = ErasedFutureProj)] +pub enum ErasedFuture<'a, T> { + Boxed(Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>), + Ready(#[pin] core::future::Ready<T>), +} + +pub enum BoxOrReady<'a, T> { + Boxed(Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>), + Ready(T), +} + +pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>; + +impl<'a, T: Send + Sync> ErasedForLt<'a, T, Async, &'a T> for ErasedHrt<T> { + type T = BoxOrReady<'a, T>; +} + +pub struct Value<T>(pub T); + +pub struct Wrapped<F>(pub F); + +impl Effect for Async { + type Erased<T: Send + Sync> = ErasedHrt<T>; + + type Ready<'a, T: Send + Sync + 'a> = Value<T>; + + fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> { + todo!() + } + + type FromFuture<'a, F: Send + Sync + 'a> = Wrapped<F> + where + F: futures::prelude::Future, + F::Output: Send + Sync + 'a; + + fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> + where + F: futures::prelude::Future, + F::Output: Send + Sync + 'a, + { + todo!() + } +} + +impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { + fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> { + self + } + + type Effect = Async; + + type Output = U; + + type IntoFuture = ErasedFuture<'lt, U>; + + fn into_future(self) -> Self::IntoFuture { + match self { + BoxOrReady::Boxed(fut) => ErasedFuture::Boxed(fut), + BoxOrReady::Ready(value) => ErasedFuture::Ready(core::future::ready(value)), + } + } + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = futures::future::Map<ErasedFuture<'lt, U>, F> + where + F: FnOnce(Self::Output) -> T, + 'lt: 'a; + + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> + where + F: FnOnce(Self::Output) -> T, + 'lt: 'a + { + todo!() + } + + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Then<ErasedFuture<'lt, U>, V::IntoFuture, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect>; + + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect> { + todo!() + } + + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = BoxedFuture<'a, T> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; + + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a { + todo!() + } +} + +impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { + fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> { + todo!() + } + + type Effect = Async; + + type Output = U; + + type IntoFuture = core::future::Ready<U>; + + fn into_future(self) -> Self::IntoFuture { + core::future::ready(self.0) + } + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = core::future::Ready<T> + where + F: FnOnce(Self::Output) -> T; + + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> + where + F: FnOnce(Self::Output) -> T { + todo!() + } + + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + = V + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect>; + + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect> { + todo!() + } + + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = BoxedFuture<'a, T> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; + + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a { + todo!() + } +} + +impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Wrapped<U> +where + U: Future, + U::Output: Send + Sync + 'lt +{ + fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> { + todo!() + } + + type Effect = Async; + + type Output = U::Output; + + type IntoFuture = U; + + fn into_future(self) -> Self::IntoFuture { + todo!() + } + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Map<U, F> + where + F: FnOnce(Self::Output) -> T; + + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> + where + F: FnOnce(Self::Output) -> T { + todo!() + } + + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Then<U, V::IntoFuture, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect>; + + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect> { + todo!() + } + + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = BoxedFuture<'a, T> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; + + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a { + todo!() + } +} + +impl Join for Async { + type Effect = Self; + + type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> + = futures::future::Join<ErasedFuture<'a, T0>, ErasedFuture<'a, T1>> + where + T0: super::Effective<'a, Effect = Self::Effect>, + T1: super::Effective<'a, Effect = Self::Effect>; + + type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = futures::future::Join3<ErasedFuture<'a, T0>, ErasedFuture<'a, T1>, ErasedFuture<'a, T2>, > + where + T0: super::Effective<'a, Effect = Self::Effect>, + T1: super::Effective<'a, Effect = Self::Effect>, + T2: super::Effective<'a, Effect = Self::Effect>; + + fn two< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, T0, T1> + where + T0: super::Effective<'a, Effect = Self::Effect>, + T1: super::Effective<'a, Effect = Self::Effect>, + F0: FnOnce() -> T0, + F1: FnOnce() -> T1 { + todo!() + } + + fn three< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( + effectives: (F0, F1, F2), + ) -> Self::Three<'a, T0, T1, T2> + where + T0: super::Effective<'a, Effect = Self::Effect>, + T1: super::Effective<'a, Effect = Self::Effect>, + T2: super::Effective<'a, Effect = Self::Effect>, + F0: FnOnce() -> T0, + F1: FnOnce() -> T1, + F2: FnOnce() -> T2 { + todo!() + } +} + +impl TryJoin for Async { + type Effect = Self; + + type Two<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> + = futures::future::TryJoin<ErasedFuture<'a, Result<T0, Err>>, ErasedFuture<'a, Result<T1, Err>>> + where + V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>; + + type Three<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, V2: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> + = futures::future::TryJoin3<ErasedFuture<'a, Result<T0, Err>>, ErasedFuture<'a, Result<T1, Err>>, ErasedFuture<'a, Result<T1, Err>>> + where + V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: super::Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>; + + fn two< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, Err, V0, V1, T0, T1> + where + V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1 { + todo!() + } + + fn three< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + V2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( + cb: (F0, F1, F2), + ) -> Self::Three<'a, Err, V0, V1, V2, T0, T1, T2> + where + V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: super::Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1, + F2: FnOnce() -> V2 { + todo!() + } +} + +impl<'lt, T> Future for ErasedFuture<'lt, T> { + type Output = T; + + fn poll(self: Pin<&mut Self>, cx: &mut core::task::Context<'_>) -> core::task::Poll<Self::Output> { + match self.project() { + ErasedFutureProj::Boxed(fut) => fut.poll_unpin(cx), + ErasedFutureProj::Ready(fut) => fut.poll(cx), + } + } +} + +impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, F0: Send + Sync + 'c, R0: Send + Sync + 'c> Effective<'c> for futures::future::Map<Fut0, F0> +where + F0: FnOnce(Fut0::Output) -> R0, + Fut0: Future, + Fut0::Output: 'lt, +{ + fn into_erased(self) -> super::ErasedEffective<'c, Self::Output, Self::Effect> { + todo!() + } + + type Effect = Async; + + type Output = R0; + + type IntoFuture = Self; + + fn into_future(self) -> Self::IntoFuture { + self + } + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = + futures::future::Map<Self, F> + where + F: FnOnce(Self::Output) -> T, + 'c: 'a; + + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> + where + F: FnOnce(Self::Output) -> T, + 'c: 'a + { + todo!() + } + + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Then<Self, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect>; + + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect> { + todo!() + } + + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = BoxOrReady<'a, T> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'a: 'a; + + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'a: 'a { + todo!() + } +} + +impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, V0: Send + Sync + 'lt, Fut1: Send + Sync + 'lt, F0: Send + Sync + 'c> Effective<'c> for futures::future::Then<Fut0, Fut1, F0> +where + F0: FnOnce(Fut0::Output) -> V0, + V0: Effective<'lt, Effect = Async, IntoFuture = Fut1>, + Fut1: Future, + Fut1::Output: Send + Sync + 'lt, + Fut0: Future, + Fut0::Output: Send + Sync + 'lt, +{ + fn into_erased(self) -> super::ErasedEffective<'c, Self::Output, Self::Effect> { + todo!() + } + + type Effect = Async; + + type Output = Fut1::Output; + + type IntoFuture = Self; + + fn into_future(self) -> Self::IntoFuture { + todo!() + } + + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Map<Self, F> + where + F: FnOnce(Self::Output) -> T, + 'c: 'a; + + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> + where + F: FnOnce(Self::Output) -> T, + 'c: 'a { + todo!() + } + + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + = futures::future::Then<Self, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect>; + + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> + where + F: FnOnce(Self::Output) -> V, + V: Effective<'a, Output = T, Effect = Self::Effect> { + todo!() + } + + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + = BoxOrReady<'a, T> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'c: 'a; + + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + where + F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, + 'c: 'a { + todo!() + } +} diff --git a/src/effect/blocking.rs b/src/effect/blocking.rs index ea97477..abadfb2 100644 --- a/src/effect/blocking.rs +++ b/src/effect/blocking.rs @@ -1,164 +1,253 @@ +mod spin; + +pub use spin::*; + +use crate::hkt::Marker; + use super::*; -pub enum Blocking {} +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; +} + +pub struct Blocking<B>(Marker<B>); -pub struct Value<T>(pub T); +#[repr(transparent)] +pub struct Value<T, B>(pub T, Marker<B>); + +impl<'lt, T: Send + Sync, B: BlockOn> ErasedForLt<'lt, T, Blocking<B>, &'lt T> for Value<T, B> { + type T = Value<T, B>; +} -impl Effect for Blocking { - type Erased<T> = Value<T>; +impl<B: BlockOn> Effect for Blocking<B> { + type Erased<T: Send + Sync> = Value<T, B>; - type Ready<T> = Value<T>; + type Ready<'a, T: Send + Sync + 'a> = Value<T, B>; - fn ready<T>(value: T) -> Self::Ready<T> { - todo!() + fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> { + Value(value, Default::default()) } - type FromFuture<F> = Value<F::Output> + type FromFuture<'a, F: Send + Sync + 'a> = Value<F::Output, B> where - F: Future; + F: Future, + F::Output: Send + Sync + 'a; - fn from_future<F>() -> Self::FromFuture<F> + fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> where F: Future, + F::Output: Send + Sync + 'a, { - todo!() + Value(B::block_on(future), Default::default()) } } -impl<U> Effective for Value<U> { - type Effect = Blocking; +impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { + fn into_erased(self) -> ErasedEffective<'lt, Self::Output, Self::Effect> { + self + } + + type Effect = Blocking<B>; type Output = U; type IntoFuture = core::future::Ready<U>; fn into_future(self) -> Self::IntoFuture { - todo!() - } - - type Loop<T, V, F> = Value<T> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>; - - fn r#loop<T, V, F>(self, cb: F) -> Self::Loop<T, V, F> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>, - { - todo!() + core::future::ready(self.0) } - type Map<T, F> = Value<T> + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B> where F: FnOnce(Self::Output) -> T; - fn map<T, F>(self, cb: F) -> Self::Map<T, F> + fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, { - todo!() + Value(cb(self.0), Default::default()) } - type Then<T, V, F> = Value<T> + type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B> where F: FnOnce(Self::Output) -> V, - V: Effective<Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>; - fn then<T, V, F>(self, cb: F) -> Self::Then<T, V, F> + fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( + self, + cb: F, + ) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, - V: Effective<Output = T, Effect = Self::Effect>, + V: Effective<'a, Output = T, Effect = Self::Effect>, { - todo!() + cb(self.0).into_erased() } - type AsCtx<T, V, F> = Value<T> + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<(U, T), B> where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>; + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; - fn as_ctx<T, V, F>(self, cb: F) -> Self::AsCtx<T, V, F> + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>, + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a, { - todo!() + let mut this = self.0; + let result = cb(&mut this).0; + Value((this, result), Default::default()) } } -impl Join for Blocking { - type Effect = Self; +impl<B: BlockOn> Join for Blocking<B> { + type Effect = Blocking<B>; - type Two<T0, T1> = Value<(T0::Output, T1::Output)> + type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<(T0::Output, T1::Output), B> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>; + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>; - type Three<T0, T1, T2> = Value<(T0::Output, T1::Output, T2::Output)> + type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<(T0::Output, T1::Output, T2::Output), B> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>; + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, + T2: Effective<'a, Effect = Self::Effect>; - fn two<T0, T1, F0, F1>(cb: (F0, F1)) -> Self::Two<T0, T1> + fn two< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, T0, T1> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, F0: FnOnce() -> T0, F1: FnOnce() -> T1, { - todo!() + let v0 = (cb.0)().into_erased().0; + let v1 = (cb.1)().into_erased().0; + + Value((v0, v1), Default::default()) } - fn three<T0, T1, T2, F0, F1, F2>(effectives: (F0, F1, F2)) -> Self::Three<T0, T1, T2> + fn three< + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( + cb: (F0, F1, F2), + ) -> Self::Three<'a, T0, T1, T2> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>, + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, + T2: Effective<'a, Effect = Self::Effect>, F0: FnOnce() -> T0, F1: FnOnce() -> T1, F2: FnOnce() -> T2, { - todo!() + let v0 = (cb.0)().into_erased().0; + let v1 = (cb.1)().into_erased().0; + let v2 = (cb.2)().into_erased().0; + + Value((v0, v1, v2), Default::default()) } } -impl TryJoin for Blocking { - type Effect = Self; - - type Two<Err, V0, V1, T0, T1> = Value<Result<(T0, T1), Err>> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>; +impl<B: BlockOn> TryJoin for Blocking<B> { + type Effect = Blocking<B>; + + type Two<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<Result<(T0, T1), Err>, B> + where + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>; + + type Three<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, V2: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<Result<(T0, T1, T2), Err>, B> + where + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>; + + fn two< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + >( + cb: (F0, F1), + ) -> Self::Two<'a, Err, V0, V1, T0, T1> + where + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1, + { + let v0 = match (cb.0)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; - type Three<Err, V0, V1, V2, T0, T1, T2> = Value<Result<(T0, T1, T2), Err>> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>; + let v1 = match (cb.1)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; - fn two<Err, T0, T1, V0, V1, F0, F1>(cb: (F0, F1)) -> Self::Two<Err, V0, V1, T0, T1> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - { - todo!() + Value(Ok((v0, v1)), Default::default()) } - fn three<Err, T0, T1, T2, V0, V1, V2, F0, F1, F2>( + fn three< + 'a, + Err: Send + Sync + 'a, + T0: Send + Sync + 'a, + T1: Send + Sync + 'a, + T2: Send + Sync + 'a, + V0: Send + Sync + 'a, + V1: Send + Sync + 'a, + V2: Send + Sync + 'a, + F0: Send + Sync + 'a, + F1: Send + Sync + 'a, + F2: Send + Sync + 'a, + >( cb: (F0, F1, F2), - ) -> Self::Three<Err, V0, V1, V2, T0, T1, T2> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - F2: FnOnce() -> T2, + ) -> Self::Three<'a, Err, V0, V1, V2, T0, T1, T2> + where + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>, + V2: Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>, + F0: FnOnce() -> V0, + F1: FnOnce() -> V1, + F2: FnOnce() -> V2, { - todo!() + let v0 = match (cb.0)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; + + let v1 = match (cb.1)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; + + let v2 = match (cb.2)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; + + Value(Ok((v0, v1, v2)), Default::default()) } } diff --git a/src/effect/blocking/spin.rs b/src/effect/blocking/spin.rs new file mode 100644 index 0000000..2193a3d --- /dev/null +++ b/src/effect/blocking/spin.rs @@ -0,0 +1,46 @@ +use core::{ + pin::pin, + ptr, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, +}; + +use super::BlockOn; + +/// [`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) } +} @@ -70,10 +70,11 @@ macro_rules! higher_ranked_trait { $($($lower_where)*)? $($($higher_where)*)? { - type T: RaiseForLt<$($lt,)+ $($($generic)*,)? B, HigherRanked = Self> + ?Sized + $($lower)*; + type T: RaiseForLt<$($lt,)+ $($($generic)*,)? B, HigherRanked = Self, HigherRankedAll = Self> + ?Sized + $($lower)*; } pub trait RaiseForLt<$($lt,)+ $($($generic)*,)? B> + : RaiseForLtAll<$($($generic)*,)? B> where $($($lower_where)*)? $($($higher_where)*)? @@ -81,6 +82,13 @@ macro_rules! higher_ranked_trait { type HigherRanked: LowerForLt<$($lt,)+ $($($generic)*,)? B, T = Self> + ?Sized + $($higher)*; } + pub trait RaiseForLtAll<$($($generic)*,)? B> + where + $($($higher_where)*)? + { + type HigherRankedAll: for<$($lt,)+> LowerForLt<$($lt,)+ $($($generic)*,)? $bound> + ?Sized + $($higher)*; + } + pub type Bound<$($lt,)+ $($($generic)*)?> = $bound; pub trait MemberType$(<$($generic)*>)?: @@ -113,6 +121,9 @@ macro_rules! higher_ranked_trait { pub type HigherRanked<$($lt,)+ $($($generic)*,)? __> = <__ as RaiseForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRanked; + + pub type HigherRankedAll<$($lt,)+ $($($generic)*,)? __> = + <__ as RaiseForLtAll<$($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRankedAll; } } } @@ -127,9 +138,13 @@ macro_rules! higher_ranked_type { $lower:ty $(where {$($lower_where:tt)*})?; - impl$([$($higher_generic:tt)*])? type HigherRanked[$($higher_forward:tt)*] for $higher_lower:ty = + impl$([$($higher_generic:tt)*])? type HigherRanked[$($higher_lt:lifetime),+]$([$($higher_forward:tt)*])? for $higher_lower:ty = $higher:ty $(where {$($higher_where:tt)*})?; + + impl$([$($higher_all_generic:tt)*])? type HigherRankedAll[$($higher_all_lt:lifetime),+]$([$($higher_all_forward:tt)*])? for $higher_all_lower:ty = + $higher_all:ty + $(where {$($higher_all_where:tt)*})?; } } => { impl$(<$($lower_generic)*>)* $higher_trait::LowerForLt<$($lower_forward)*, $higher_trait::Bound<$($lower_forward)*>> for $lower_higher @@ -138,11 +153,17 @@ macro_rules! higher_ranked_type { type T = $lower; } - impl$(<$($higher_generic)*>)* $higher_trait::RaiseForLt<$($higher_forward)*, $higher_trait::Bound<$($higher_forward)*>> for $higher_lower + impl$(<$($higher_generic)*>)* $higher_trait::RaiseForLt<$($higher_lt,)+ $($($higher_forward)*,)? $higher_trait::Bound<$($higher_lt,)+ $($($higher_forward)*)?>> for $higher_lower $(where $($higher_where)*)? { type HigherRanked = $higher; } + + impl$(<$($higher_all_generic)*>)* $higher_trait::RaiseForLtAll<$($($higher_all_forward)*,)? $higher_trait::Bound<$($higher_all_lt,)+ $($($higher_all_forward)*)?>> for $higher_all_lower + $(where $($higher_all_where)*)? + { + type HigherRankedAll = $higher_all; + } } } pub use higher_ranked_type; |