Diffstat (limited to 'src/effect.rs')
| -rw-r--r-- | src/effect.rs | 234 |
1 files changed, 154 insertions, 80 deletions
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; } |