Diffstat (limited to 'src/effect.rs')
-rw-r--r--src/effect.rs234
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;
}