Diffstat (limited to 'src/effect.rs')
| -rw-r--r-- | src/effect.rs | 251 |
1 files changed, 172 insertions, 79 deletions
diff --git a/src/effect.rs b/src/effect.rs index e8891ad..0c85769 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -58,22 +58,19 @@ pub trait Effect: F::Output: Send + Sync + 'a; } -pub trait ErasedForLt<'a, T: Send + Sync + 'a, E: Effect, Bound: 'a> { +pub trait ErasedForLt<'a, T: Send + Sync + 'a, E: Effect, Bound: 'a, O: 'a> { type T: Effective<'a, Output = T, Effect = E>; } -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 trait ErasedHrt<T: Send + Sync, E: Effect> { + type T<B>: for<'a> ErasedForLt<'a, T, E, &'a (T, B), B>; } -pub type ErasedEffective<'lt, Output, E> = - <<E as Effect>::Erased<Output> as ErasedForLt<'lt, Output, E, &'lt Output>>::T; +pub type ErasedEffective<'lt, Output, E, B = ()> = + <<<E as Effect>::Erased<Output> as ErasedHrt<Output, E>>::T<B> as ErasedForLt<'lt, Output, E, &'lt (Output, B), B>>::T; pub trait Effective<'lt>: Send + Sync + 'lt { - fn into_erased(self) -> ErasedEffective<'lt, Self::Output, Self::Effect>; + fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B>; /// The effect the effective belongs to. type Effect: Effect; @@ -87,18 +84,19 @@ pub trait Effective<'lt>: Send + Sync + 'lt { /// 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: 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 Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + 'a, + Output = (Self::Output, T), + Effect = Self::Effect, + > + where + F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 'lt: 'a; + + fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Loop<'ctx, 'a, T, F> + where + F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 'lt: 'a; type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< 'a, @@ -121,7 +119,8 @@ pub trait Effective<'lt>: Send + Sync + 'lt { > where F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>, + 'lt: 'a; fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( self, @@ -129,23 +128,40 @@ pub trait Effective<'lt>: Send + Sync + 'lt { ) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>, + 'lt: 'a; - type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< 'a, Output = (Self::Output, T), Effect = Self::Effect, > where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, 'lt: 'a; - fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, 'lt: 'a; } +pub trait TryEffective<'lt>: Effective<'lt, Output = Result<Self::Ok, Self::Err>> { + type Ok: Send + Sync + 'lt; + type Err: Send + Sync + 'lt; +} + +impl<'lt, T, Ok, Err> TryEffective<'lt> for T +where + T: Effective<'lt, Output = Result<Ok, Err>>, + Ok: Send + Sync + 'lt, + Err: Send + Sync + 'lt, +{ + type Ok = Ok; + + type Err = Err; +} + pub trait Join { type Effect: Effect; @@ -168,96 +184,173 @@ pub trait Join { 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), + fn two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>( + effectives: (T0, T1), ) -> Self::Two<'a, T0, T1> where T0: Effective<'a, Effect = Self::Effect>, - T1: Effective<'a, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1; + T1: Effective<'a, Effect = Self::Effect>; - 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), + fn three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>( + effectives: (T0, T1, T2), ) -> Self::Three<'a, T0, T1, T2> where 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; + T2: Effective<'a, Effect = Self::Effect>; } pub trait TryJoin { type Effect: 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> + type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>: Effective< + 'a, + Output = Result<(T0::Ok, T1::Ok), T0::Err>, + Effect = Self::Effect, + > where - V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>; + T0: TryEffective<'a, Effect = Self::Effect>, + T1: TryEffective<'a, Err = T0::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>: Effective<'a, - Output = Result<(T0, T1, T2), Err>, + type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>: Effective< + 'a, + Output = Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, Effect = Self::Effect, > 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>; + T0: TryEffective<'a, Effect = Self::Effect>, + T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + T2: TryEffective<'a, Err = T0::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> + ) -> Self::Two<'a, 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; + T0: TryEffective<'a, Effect = Self::Effect>, + T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + F0: FnOnce() -> T0, + F1: FnOnce() -> T1; 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> + ) -> Self::Three<'a, 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; + T0: TryEffective<'a, Effect = Self::Effect>, + T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + T2: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + F0: FnOnce() -> T0, + F1: FnOnce() -> T1, + F2: FnOnce() -> T2; +} + +pub fn join<'lt, E: Effect, T: Joinable<'lt, E>>(x: T) -> T::Output { + x.join() +} + +pub trait Joinable<'lt, E: Effect> { + type Output: Effective<'lt, Effect = E>; + + fn join(self) -> Self::Output; +} + +impl<'lt, E: Effect> Joinable<'lt, E> for () { + type Output = E::Ready<'lt, ()>; + + fn join(self) -> Self::Output { + E::ready(()) + } +} + +impl<'lt, E: Effect, T0> Joinable<'lt, E> for (T0,) +where + T0: Effective<'lt, Effect = E>, +{ + type Output = T0; + + fn join(self) -> Self::Output { + self.0 + } +} + +impl<'lt, E: Effect, T0, T1> Joinable<'lt, E> for (T0, T1) +where + T0: Effective<'lt, Effect = E>, + T1: Effective<'lt, Effect = E>, +{ + type Output = <E as Join>::Two<'lt, T0, T1>; + + fn join(self) -> Self::Output { + <E as Join>::two(self) + } +} + +impl<'lt, E: Effect, T0, T1, T2> Joinable<'lt, E> for (T0, T1, T2) +where + T0: Effective<'lt, Effect = E>, + T1: Effective<'lt, Effect = E>, + T2: Effective<'lt, Effect = E>, +{ + type Output = <E as Join>::Three<'lt, T0, T1, T2>; + + fn join(self) -> Self::Output { + <E as Join>::three(self) + } +} + +pub fn try_join<'lt, E: Effect, T: TryJoinable<'lt, E>>(x: T) -> T::Output { + x.join() +} + +pub trait TryJoinable<'lt, E: Effect> { + type Output: TryEffective<'lt, Effect = E>; + + fn join(self) -> Self::Output; +} + +impl<'lt, E: Effect> TryJoinable<'lt, E> for () { + type Output = E::Ready<'lt, Result<(), ()>>; + + fn join(self) -> Self::Output { + E::ready(Ok(())) + } +} + +impl<'lt, E: Effect, F0, T0> TryJoinable<'lt, E> for (F0,) +where + F0: FnOnce() -> T0, + T0: TryEffective<'lt, Effect = E>, +{ + type Output = T0; + + fn join(self) -> Self::Output { + self.0() + } +} + +impl<'lt, E: Effect, F0, F1, T0, T1> TryJoinable<'lt, E> for (F0, F1) +where + F0: FnOnce() -> T0 + Send + Sync + 'lt, + F1: FnOnce() -> T1 + Send + Sync + 'lt, + T0: TryEffective<'lt, Effect = E>, + T1: TryEffective<'lt, Err = T0::Err, Effect = E>, +{ + type Output = <E as TryJoin>::Two<'lt, T0, T1>; + + fn join(self) -> Self::Output { + <E as TryJoin>::two(self) + } } |