| -rw-r--r-- | src/build/builders/core/struct.rs | 4 | ||||
| -rw-r--r-- | src/effect.rs | 202 | ||||
| -rw-r--r-- | src/effect/async.rs | 384 | ||||
| -rw-r--r-- | src/effect/async/map.rs | 165 | ||||
| -rw-r--r-- | src/effect/async/shim.rs | 116 | ||||
| -rw-r--r-- | src/effect/async/then.rs | 184 | ||||
| -rw-r--r-- | src/effect/async/value.rs | 98 | ||||
| -rw-r--r-- | src/effect/blocking.rs | 32 | ||||
| -rw-r--r-- | src/protocol/visitor.rs | 12 | ||||
| -rw-r--r-- | src/protocol/visitor/sequence.rs | 4 |
10 files changed, 309 insertions, 892 deletions
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 9ff1862..e011eff 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -163,7 +163,7 @@ impl<'ctx, Info, Mode: 'ctx, E: Effect> StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode>, { - fn make_builders<'e>(&mut self) -> ErasedEffective<'e, (), E> + fn make_builders<'e>(&'e mut self) -> ErasedEffective<'e, (), E> where 'ctx: 'e, { @@ -399,7 +399,7 @@ where let mut index = 0; // Loop through all the fields getting a value for each one. - E::repeat_map((scope, builders), |(scope, builders)| { + E::repeat_map((scope, builders), move |(scope, builders)| { // Get the marker for the field at this index. let marker = tri!(Info::marker_from_index(index)); diff --git a/src/effect.rs b/src/effect.rs index 50dab50..092705e 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -1,4 +1,4 @@ -// pub mod r#async; +pub mod r#async; pub mod blocking; use core::{future::Future, ops::ControlFlow}; @@ -217,7 +217,8 @@ pub use tri; pub trait EffectExt: Effect { fn repeat_map<'ctx, 'wrap, I, U, F>(input: I, f: F) -> ErasedEffective<'wrap, U, Self> where - F: for<'temp> FnMut(&'temp mut I) -> ErasedEffective<'temp, ControlFlow<U>, Self, &'ctx ()>, + F: 'wrap + + for<'temp> FnMut(&'temp mut I) -> ErasedEffective<'temp, ControlFlow<U>, Self, &'ctx ()>, I: Ss + 'wrap, U: Ss, F: Ss, @@ -229,7 +230,7 @@ pub trait EffectExt: Effect { #[inline(always)] fn as_ctx<'ctx, 'wrap, I, U, F>(input: I, f: F) -> ErasedEffective<'wrap, (I, U), Self> where - F: for<'temp> FnOnce(&'temp mut I) -> ErasedEffective<'temp, U, Self, &'ctx ()>, + F: 'wrap + for<'temp> FnOnce(&'temp mut I) -> ErasedEffective<'temp, U, Self, &'ctx ()>, I: Ss + 'wrap, U: Ss, F: Ss, @@ -240,7 +241,7 @@ pub trait EffectExt: Effect { fn as_ctx_map<'ctx, 'wrap, I, U, F>(input: I, f: F) -> ErasedEffective<'wrap, U, Self> where - F: for<'temp> FnOnce(&'temp mut I) -> ErasedEffective<'temp, U, Self, &'ctx ()>, + F: 'wrap + for<'temp> FnOnce(&'temp mut I) -> ErasedEffective<'temp, U, Self, &'ctx ()>, I: Ss + 'wrap, U: Ss, F: Ss, @@ -271,7 +272,7 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { fn map<'wrap, U, F>(self, f: F) -> ErasedEffective<'wrap, U, Self::Effect> where - F: FnOnce(Self::Output) -> U, + F: 'wrap + FnOnce(Self::Output) -> U, U: Ss, F: Ss, 'lt: 'wrap, @@ -288,7 +289,7 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { fn then<'wrap, U, F>(self, f: F) -> ErasedEffective<'wrap, U, Self::Effect> where - F: FnOnce(Self::Output) -> ErasedEffective<'wrap, U, Self::Effect>, + F: 'wrap + FnOnce(Self::Output) -> ErasedEffective<'wrap, U, Self::Effect>, U: Ss, F: Ss, 'lt: 'wrap, @@ -306,7 +307,7 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { fn or_else<'wrap, U, F>(self, f: F) -> ErasedEffective<'wrap, Option<U>, Self::Effect> where Self: Effective<'lt, Output = Option<U>>, - F: FnOnce() -> ErasedEffective<'wrap, Option<U>, Self::Effect>, + F: 'wrap + FnOnce() -> ErasedEffective<'wrap, Option<U>, Self::Effect>, U: Ss, F: Ss, 'lt: 'wrap, @@ -336,9 +337,10 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { f: F, ) -> ErasedEffective<'wrap, (Self::Output, U), Self::Effect> where - F: for<'temp> FnOnce( - &'temp mut Self::Output, - ) -> ErasedEffective<'temp, U, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnOnce( + &'temp mut Self::Output, + ) -> ErasedEffective<'temp, U, Self::Effect, &'ctx ()>, U: Ss, F: Ss, 'ctx: 'lt, @@ -358,9 +360,10 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { #[allow(clippy::wrong_self_convention)] fn as_ctx_map<'ctx, 'wrap, U, F>(self, f: F) -> ErasedEffective<'wrap, U, Self::Effect> where - F: for<'temp> FnOnce( - &'temp mut Self::Output, - ) -> ErasedEffective<'temp, U, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnOnce( + &'temp mut Self::Output, + ) -> ErasedEffective<'temp, U, Self::Effect, &'ctx ()>, 'ctx: 'lt, U: Ss, F: Ss, @@ -383,9 +386,11 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { ) -> ErasedEffective<'wrap, (Ctx, Option<U>), Self::Effect> where Self: Effective<'lt, Output = (Ctx, Option<U>)>, - F: for<'temp> FnOnce( - &'temp mut Ctx, - ) -> ErasedEffective<'temp, Option<U>, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnOnce( + &'temp mut Ctx, + ) + -> ErasedEffective<'temp, Option<U>, Self::Effect, &'ctx ()>, 'ctx: 'lt, Ctx: Ss, U: Ss, @@ -417,9 +422,11 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { ) -> ErasedEffective<'wrap, Option<U>, Self::Effect> where Self: Effective<'lt, Output = (Ctx, Option<U>)>, - F: for<'temp> FnOnce( - &'temp mut Ctx, - ) -> ErasedEffective<'temp, Option<U>, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnOnce( + &'temp mut Ctx, + ) + -> ErasedEffective<'temp, Option<U>, Self::Effect, &'ctx ()>, 'ctx: 'lt, Ctx: Ss, U: Ss, @@ -449,10 +456,11 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { mut f: F, ) -> ErasedEffective<'wrap, (Self::Output, U), Self::Effect> where - F: for<'temp> FnMut( - &'temp mut Self::Output, - ) - -> ErasedEffective<'temp, ControlFlow<U>, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnMut( + &'temp mut Self::Output, + ) + -> ErasedEffective<'temp, ControlFlow<U>, Self::Effect, &'ctx ()>, 'ctx: 'lt, U: Ss, F: Ss, @@ -462,7 +470,7 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { |ctx| (ctx, ControlFlow::Continue(())), |_, _| <Self::Effect as Effect>::ready(()).cast(), |_, _| ControlFlow::Continue(()), - |ctx, _| f(ctx).cast(), + move |ctx, _| f(ctx).cast(), |_, _, v| v, |ctx, _, v| (ctx, v), ) @@ -470,10 +478,11 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { fn repeat_map<'ctx, 'wrap, U, F>(self, mut f: F) -> ErasedEffective<'wrap, U, Self::Effect> where - F: for<'temp> FnMut( - &'temp mut Self::Output, - ) - -> ErasedEffective<'temp, ControlFlow<U>, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnMut( + &'temp mut Self::Output, + ) + -> ErasedEffective<'temp, ControlFlow<U>, Self::Effect, &'ctx ()>, 'ctx: 'lt, U: Ss, F: Ss, @@ -483,7 +492,7 @@ pub trait EffectiveExt<'lt>: Effective<'lt> { |ctx| (ctx, ControlFlow::Continue(())), |_, _| <Self::Effect as Effect>::ready(()).cast(), |_, _| ControlFlow::Continue(()), - |ctx, _| f(ctx).cast(), + move |ctx, _| f(ctx).cast(), |_, _, v| v, |_, _, v| v, ) @@ -537,26 +546,34 @@ pub trait Effective<'lt>: Sized + Ss + 'lt { post: Post, ) -> ErasedEffective<'wrap, Return, Self::Effect> where - Pre: Ss + FnOnce(Self::Output) -> (Ctx, ControlFlow<Done, Owned>), + Pre: Ss + 'wrap + FnOnce(Self::Output) -> (Ctx, ControlFlow<Done, Owned>), First: Ss + + 'wrap + for<'temp> FnOnce( &'temp mut Ctx, Owned, ) -> ErasedEffective<'temp, FirstOutput, Self::Effect, &'wrap ()>, - FirstPost: Ss + for<'temp> FnOnce(&'temp mut Ctx, FirstOutput) -> ControlFlow<Done, Extra>, + FirstPost: + Ss + 'wrap + for<'temp> FnOnce(&'temp mut Ctx, FirstOutput) -> ControlFlow<Done, Extra>, Repeat: Ss + + 'wrap + for<'temp> FnMut( &'temp mut Ctx, &'temp mut Extra, ) -> ErasedEffective<'temp, RepeatOutput, Self::Effect, &'wrap ()>, RepeatPost: Ss + + 'wrap + for<'temp> FnMut(&'temp mut Ctx, &'temp mut Extra, RepeatOutput) -> ControlFlow<Done>, - Post: Ss + FnOnce(Ctx, Option<Extra>, Done) -> Return, + Post: Ss + 'wrap + FnOnce(Ctx, Option<Extra>, Done) -> Return, Return: Ss, RepeatOutput: Ss, FirstOutput: Ss, + Owned: Ss, + Done: Ss, + Ctx: Ss, + Extra: Ss, 'lt: 'wrap; } @@ -579,31 +596,16 @@ where pub trait Join { type Effect: Effect; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a>: Effective< - 'a, - Output = (T0::Output, T1::Output), - Effect = Self::Effect, - > - where - T0: Effective<'a, Effect = Self::Effect>, - T1: Effective<'a, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>: Effective< - 'a, - Output = (T0::Output, T1::Output, T2::Output), - Effect = Self::Effect, - > - where - T0: Effective<'a, Effect = Self::Effect>, - T1: Effective<'a, Effect = Self::Effect>, - T2: Effective<'a, Effect = Self::Effect>; - - fn two<'a, T0, T1>(effectives: (T0, T1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0, T1>( + effectives: (T0, T1), + ) -> ErasedEffective<'a, (T0::Output, T1::Output), Self::Effect> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>; - fn three<'a, T0, T1, T2>(effectives: (T0, T1, T2)) -> Self::Three<'a, T0, T1, T2> + fn three<'a, T0, T1, T2>( + effectives: (T0, T1, T2), + ) -> ErasedEffective<'a, (T0::Output, T1::Output, T2::Output), Self::Effect> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, @@ -613,33 +615,18 @@ pub trait Join { pub trait TryJoin { type Effect: Effect; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a>: Effective< - 'a, - Output = Result<(T0::Ok, T1::Ok), T0::Err>, - Effect = Self::Effect, - > - where - T0: TryEffective<'a, Effect = Self::Effect>, - T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>: Effective< - 'a, - Output = Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, - Effect = Self::Effect, - > - where - 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, T0, T1, F0, F1>(cb: (F0, F1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0, T1, F0, F1>( + cb: (F0, F1), + ) -> ErasedEffective<'a, Result<(T0::Ok, T1::Ok), T0::Err>, Self::Effect> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, F0: Ss + 'a + FnOnce() -> T0, F1: Ss + 'a + FnOnce() -> T1; - fn three<'a, T0, T1, T2, F0, F1, F2>(cb: (F0, F1, F2)) -> Self::Three<'a, T0, T1, T2> + fn three<'a, T0, T1, T2, F0, F1, F2>( + cb: (F0, F1, F2), + ) -> ErasedEffective<'a, Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, Self::Effect> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, @@ -649,20 +636,20 @@ pub trait TryJoin { F2: Ss + 'a + FnOnce() -> T2; } -pub fn join<'lt, E: Effect, T: Joinable<'lt, E>>(x: T) -> T::Output { +pub fn join<'lt, E: Effect, T: Joinable<'lt, E>>(x: T) -> ErasedEffective<'lt, T::Output, E> { x.join() } pub trait Joinable<'lt, E: Effect> { - type Output: Effective<'lt, Effect = E>; + type Output: Ss; - fn join(self) -> Self::Output; + fn join(self) -> ErasedEffective<'lt, Self::Output, E>; } impl<'lt, E: Effect> Joinable<'lt, E> for () { - type Output = ErasedEffective<'lt, (), E>; + type Output = (); - fn join(self) -> Self::Output { + fn join(self) -> ErasedEffective<'lt, (), E> { E::ready(()) } } @@ -671,10 +658,10 @@ impl<'lt, E: Effect, T0> Joinable<'lt, E> for (T0,) where T0: Effective<'lt, Effect = E>, { - type Output = T0; + type Output = (T0::Output,); - fn join(self) -> Self::Output { - self.0 + fn join(self) -> ErasedEffective<'lt, (T0::Output,), E> { + self.0.map(|x| (x,)) } } @@ -683,9 +670,9 @@ where T0: Effective<'lt, Effect = E>, T1: Effective<'lt, Effect = E>, { - type Output = <E as Join>::Two<'lt, T0, T1>; + type Output = (T0::Output, T1::Output); - fn join(self) -> Self::Output { + fn join(self) -> ErasedEffective<'lt, Self::Output, E> { <E as Join>::two(self) } } @@ -696,29 +683,34 @@ where T1: Effective<'lt, Effect = E>, T2: Effective<'lt, Effect = E>, { - type Output = <E as Join>::Three<'lt, T0, T1, T2>; + type Output = (T0::Output, T1::Output, T2::Output); - fn join(self) -> Self::Output { + fn join(self) -> ErasedEffective<'lt, Self::Output, E> { <E as Join>::three(self) } } -pub fn try_join<'lt, E: Effect, T: TryJoinable<'lt, E>>(x: T) -> T::Output { +pub fn try_join<'lt, E: Effect, T: TryJoinable<'lt, E>>( + x: T, +) -> ErasedEffective<'lt, Result<T::Ok, T::Err>, E> { x.join() } pub trait TryJoinable<'lt, E: Effect> { - type Output: TryEffective<'lt, Effect = E>; + type Ok: Ss; + type Err: Ss; - fn join(self) -> Self::Output; + fn join(self) -> ErasedEffective<'lt, Result<Self::Ok, Self::Err>, E>; } impl<'lt, E: Effect> TryJoinable<'lt, E> for () { - type Output = ErasedEffective<'lt, Result<(), ()>, E>; - - fn join(self) -> Self::Output { + fn join(self) -> ErasedEffective<'lt, Result<Self::Ok, Self::Err>, E> { E::ready(Ok(())) } + + type Ok = (); + + type Err = Never; } impl<'lt, E: Effect, F0, T0> TryJoinable<'lt, E> for (F0,) @@ -726,11 +718,13 @@ where F0: FnOnce() -> T0, T0: TryEffective<'lt, Effect = E>, { - type Output = T0; - - fn join(self) -> Self::Output { - self.0() + fn join(self) -> ErasedEffective<'lt, Result<Self::Ok, Self::Err>, E> { + self.0().map(|x| x.map(|x| (x,))) } + + type Ok = (T0::Ok,); + + type Err = T0::Err; } impl<'lt, E: Effect, F0, F1, T0, T1> TryJoinable<'lt, E> for (F0, F1) @@ -740,11 +734,13 @@ where 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 { + fn join(self) -> ErasedEffective<'lt, Result<Self::Ok, Self::Err>, E> { <E as TryJoin>::two(self) } + + type Ok = (T0::Ok, T1::Ok); + + type Err = T0::Err; } impl<'lt, E: Effect, F0, F1, F2, T0, T1, T2> TryJoinable<'lt, E> for (F0, F1, F2) @@ -756,9 +752,11 @@ where T1: TryEffective<'lt, Err = T0::Err, Effect = E>, T2: TryEffective<'lt, Err = T0::Err, Effect = E>, { - type Output = <E as TryJoin>::Three<'lt, T0, T1, T2>; - - fn join(self) -> Self::Output { + fn join(self) -> ErasedEffective<'lt, Result<Self::Ok, Self::Err>, E> { <E as TryJoin>::three(self) } + + type Ok = (T0::Ok, T1::Ok, T2::Ok); + + type Err = T0::Err; } diff --git a/src/effect/async.rs b/src/effect/async.rs index 1c0eb9d..fd0bbf0 100644 --- a/src/effect/async.rs +++ b/src/effect/async.rs @@ -1,78 +1,85 @@ -// mod join; -// mod try_join; -mod map; -mod shim; -mod then; -mod value; - -// pub use join::*; -// pub use try_join::*; -pub use map::*; -pub use shim::*; -pub use then::*; -pub use value::*; - -use core::{ops::ControlFlow, pin::Pin}; - -use core::future::Future; +use core::pin::Pin; use futures::FutureExt as _; use pin_project::pin_project; use crate::hkt::Marker; -use super::{Effect, Effective, ErasedEffective, ErasedForLt, Join, Ss, TryJoin}; +use super::*; pub enum Async {} -pub struct ErasedHrt<T>(Marker<T>); +pub struct ErasedFutureHrt<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>), +enum ErasedFutureKind<'lt, T> { + Boxed(Pin<Box<dyn Future<Output = T> + Send + Sync + 'lt>>), + Ready(T), } -pub enum BoxOrReady<'a, T> { - Boxed(Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>), - Ready(T), +pub struct ErasedFuture<'lt, T> { + kind: ErasedFutureKind<'lt, T>, } -pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>; +#[pin_project(project = EffectFutureKindProj)] +enum EffectFutureKind<'lt, T> { + Boxed(Pin<Box<dyn Future<Output = T> + Send + Sync + 'lt>>), + Ready(#[pin] ::core::future::Ready<T>), +} -impl<'a, T: Ss, O> ErasedForLt<'a, T, Async, &'a (T, O)> for ErasedHrt<T> { - type T = BoxOrReady<'a, T>; +#[pin_project] +pub struct EffectFuture<'lt, T> { + #[pin] + kind: EffectFutureKind<'lt, T>, } -impl<T: Ss> super::ErasedHrt<T, Async> for ErasedHrt<T> { - type T<B> = ErasedHrt<T>; +impl<'lt, T> Future for EffectFuture<'lt, T> { + type Output = T; + + fn poll( + self: Pin<&mut Self>, + cx: &mut core::task::Context<'_>, + ) -> core::task::Poll<Self::Output> { + let this = self.project(); + match this.kind.project() { + EffectFutureKindProj::Boxed(fut) => fut.poll_unpin(cx), + EffectFutureKindProj::Ready(fut) => fut.poll(cx), + } + } } -impl Effect for Async { - type Erased<T: Ss> = ErasedHrt<T>; +impl<'lt, T: Ss, O> Erased::ForLt<'lt, T, Async, &'lt (T, O)> for ErasedFutureHrt<T> { + type Effective = ErasedFuture<'lt, T>; +} + +impl<T: Ss> Erased::Hkt<T, Async> for ErasedFutureHrt<T> { + type Hrt<O> = Self; +} - type Ready<'a, T: Ss + 'a> = Value<T>; +impl Effect for Async { + type Erased<T: Ss> = ErasedFutureHrt<T>; - fn ready<'a, T: Ss + 'a>(value: T) -> Self::Ready<'a, T> { - Value(value) + fn ready<'a, T: Ss + 'a>(value: T) -> ErasedEffective<'a, T, Self> { + ErasedFuture { + kind: ErasedFutureKind::Ready(value), + } } - type FromFuture<'a, F: Ss + 'a> = Shim<F> - where - F: futures::prelude::Future, - F::Output: Ss + 'a; - - fn from_future<'a, F: Ss + 'a>(future: F) -> Self::FromFuture<'a, F> + fn from_future<'a, F>(future: F) -> ErasedEffective<'a, F::Output, Self> where - F: futures::prelude::Future, + F: Future + Ss + 'a, F::Output: Ss + 'a, { - Shim::new(future) + ErasedFuture { + kind: ErasedFutureKind::Boxed(Box::pin(future)), + } } } -impl<'lt, U: Ss + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { - fn into_erased<B>(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect, B> { +impl<'lt, U: Ss + 'lt> Effective<'lt> for ErasedFuture<'lt, U> { + fn cast<'wrap, X>(self) -> ErasedEffective<'wrap, Self::Output, Self::Effect, X> + where + 'lt: 'wrap, + { self } @@ -80,190 +87,183 @@ impl<'lt, U: Ss + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { type Output = U; - type IntoFuture = ErasedFuture<'lt, U>; + type IntoFuture = EffectFuture<'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)), + EffectFuture { + kind: match self.kind { + ErasedFutureKind::Boxed(fut) => EffectFutureKind::Boxed(fut), + ErasedFutureKind::Ready(value) => { + EffectFutureKind::Ready(::core::future::ready(value)) + } + }, } } - type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (U, T)> + fn r#do< + 'ctx: 'lt, + 'wrap, + Pre, + Ctx, + Owned, + First, + FirstOutput, + FirstPost, + Done, + Extra, + Repeat, + RepeatOutput, + RepeatPost, + Post, + Return, + >( + self, + pre: Pre, + first: First, + first_post: FirstPost, + mut repeat: Repeat, + mut repeat_post: RepeatPost, + post: Post, + ) -> ErasedEffective<'wrap, Return, Self::Effect> where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'lt: 'a; - - fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'lt: 'a, + Pre: Ss + 'wrap + FnOnce(Self::Output) -> (Ctx, ControlFlow<Done, Owned>), + First: Ss + + 'wrap + + for<'b> FnOnce( + &'b mut Ctx, + Owned, + ) -> ErasedEffective<'b, FirstOutput, Self::Effect, &'wrap ()>, + FirstPost: + Ss + 'wrap + for<'b> FnOnce(&'b mut Ctx, FirstOutput) -> ControlFlow<Done, Extra>, + Repeat: Ss + + 'wrap + + for<'b> FnMut( + &'b mut Ctx, + &'b mut Extra, + ) -> ErasedEffective<'b, RepeatOutput, Self::Effect, &'wrap ()>, + RepeatPost: Ss + + 'wrap + + for<'b> FnMut(&'b mut Ctx, &'b mut Extra, RepeatOutput) -> ControlFlow<Done>, + Post: 'wrap + Ss + FnOnce(Ctx, Option<Extra>, Done) -> Return, + Return: Ss, + FirstOutput: Ss, + RepeatOutput: Ss, + Owned: Ss, + Done: Ss, + Ctx: Ss, + Extra: Ss, + 'lt: 'wrap, { - BoxOrReady::Boxed(Box::pin(async move { - let mut this = self.into_future().await; - - loop { - if let ControlFlow::Break(value) = cb(&mut this).into_future().await { - return (this, value); + let fut = async move { + let (ctx, done, extra) = match pre(self.into_future().await) { + (mut ctx, ControlFlow::Continue(owned)) => { + let first_output = first(&mut ctx, owned).into_future().await; + + let (done, extra) = match first_post(&mut ctx, first_output) { + ControlFlow::Continue(mut extra) => loop { + let repeat_output = repeat(&mut ctx, &mut extra).into_future().await; + + match repeat_post(&mut ctx, &mut extra, repeat_output) { + ControlFlow::Continue(()) => {} + ControlFlow::Break(done) => break (done, Some(extra)), + } + }, + ControlFlow::Break(done) => (done, None), + }; + + (ctx, done, extra) } - } - })) - } + (ctx, ControlFlow::Break(done)) => (ctx, done, None), + }; - type Map<'a, T: Ss + 'a, F: Ss + 'a> = Map<ErasedFuture<'lt, U>, F> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a; + post(ctx, extra, done) + }; - fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a, - { - Map::new(self.into_future(), cb) - } - - type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> - = Then<'a, ErasedFuture<'lt, U>, F, V> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a; - - fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a, - { - Then::new(self.into_future(), cb) + ErasedFuture { + kind: ErasedFutureKind::Boxed(Box::pin(fut)), + } } - type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (Self::Output, T)> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, - 'lt: 'a; - - fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, - 'lt: 'a, - { - BoxOrReady::Boxed(Box::pin(async { - let mut this = self.into_future().await; - - let result = cb(&mut this).into_future().await; - - (this, result) - })) + fn ready(value: Self::Output) -> Self { + ErasedFuture { + kind: ErasedFutureKind::Ready(value), + } } } impl Join for Async { type Effect = Self; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a> - = Shim<futures::future::Join<T0::IntoFuture, T1::IntoFuture>> - where - T0: super::Effective<'a, Effect = Self::Effect>, - T1: super::Effective<'a, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> - = Shim<futures::future::Join3<T0::IntoFuture, T1::IntoFuture, T2::IntoFuture, >> - 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: Ss + 'a, T1: Ss + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0, T1>( + effectives: (T0, T1), + ) -> ErasedEffective<'a, (T0::Output, T1::Output), Self::Effect> where - T0: super::Effective<'a, Effect = Self::Effect>, - T1: super::Effective<'a, Effect = Self::Effect>, + T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, + T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, { - Shim::new(futures::future::join( - cb.0.into_future(), - cb.1.into_future(), - )) + Self::from_future(async { + let v0 = effectives.0.into_future().await; + let v1 = effectives.1.into_future().await; + + (v0, v1) + }) } - fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>( - cb: (T0, T1, T2), - ) -> Self::Three<'a, T0, T1, T2> + fn three<'a, T0, T1, T2>( + effectives: (T0, T1, T2), + ) -> ErasedEffective<'a, (T0::Output, T1::Output, T2::Output), Self::Effect> where - T0: super::Effective<'a, Effect = Self::Effect>, - T1: super::Effective<'a, Effect = Self::Effect>, - T2: super::Effective<'a, Effect = Self::Effect>, + T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, + T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, + T2: Ss + 'a + Effective<'a, Effect = Self::Effect>, { - Shim::new(futures::future::join3( - cb.0.into_future(), - cb.1.into_future(), - cb.2.into_future(), - )) + Self::from_future(async { + let v0 = effectives.0.into_future().await; + let v1 = effectives.1.into_future().await; + let v2 = effectives.2.into_future().await; + + (v0, v1, v2) + }) } } impl TryJoin for Async { type Effect = Self; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a> - = Shim<futures::future::TryJoin<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>>> - where - T0: super::TryEffective<'a, Effect = Self::Effect>, - T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> - = Shim<futures::future::TryJoin3<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>, BoxedFuture<'a, T2::Output>>> - where - T0: super::TryEffective<'a, Effect = Self::Effect>, - T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, - T2: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - - fn two<'a, T0: Ss + 'a, T1: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a>( + fn two<'a, T0, T1, F0, F1>( cb: (F0, F1), - ) -> Self::Two<'a, T0, T1> + ) -> ErasedEffective<'a, Result<(T0::Ok, T1::Ok), T0::Err>, Self::Effect> where - T0: super::TryEffective<'a, Effect = Self::Effect>, - T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, + T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, + T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + F0: Ss + 'a + FnOnce() -> T0, + F1: Ss + 'a + FnOnce() -> T1, { - Shim::new(futures::future::try_join( - Box::pin(async { cb.0().into_future().await }), - Box::pin(async { cb.1().into_future().await }), - )) + Self::from_future(async { + let v0 = cb.0().into_future().await?; + let v1 = cb.1().into_future().await?; + + Ok((v0, v1)) + }) } - fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a, F2: Ss + 'a>( + fn three<'a, T0, T1, T2, F0, F1, F2>( cb: (F0, F1, F2), - ) -> Self::Three<'a, T0, T1, T2> + ) -> ErasedEffective<'a, Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, Self::Effect> where - T0: super::TryEffective<'a, Effect = Self::Effect>, - T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, - T2: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - F2: FnOnce() -> T2, + T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, + T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + T2: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, + F0: Ss + 'a + FnOnce() -> T0, + F1: Ss + 'a + FnOnce() -> T1, + F2: Ss + 'a + FnOnce() -> T2, { - Shim::new(futures::future::try_join3( - Box::pin(async { cb.0().into_future().await }), - Box::pin(async { cb.1().into_future().await }), - Box::pin(async { cb.2().into_future().await }), - )) - } -} - -impl<'lt, T> Future for ErasedFuture<'lt, T> { - type Output = T; + Self::from_future(async { + let v0 = cb.0().into_future().await?; + let v1 = cb.1().into_future().await?; + let v2 = cb.2().into_future().await?; - 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), - } + Ok((v0, v1, v2)) + }) } } diff --git a/src/effect/async/map.rs b/src/effect/async/map.rs deleted file mode 100644 index 45bee06..0000000 --- a/src/effect/async/map.rs +++ /dev/null @@ -1,165 +0,0 @@ -use core::{ - ops::ControlFlow, - pin::Pin, - task::{Context, Poll}, -}; - -use futures::Future; -use pin_project::pin_project; - -use crate::effect::{Effective, ErasedEffective, Ss}; - -use super::{Async, BoxOrReady, Then}; - -#[pin_project(project = MapStateProj, project_replace = MapStateReplace)] -enum MapState<Fut, F> { - Incomplete { - #[pin] - future: Fut, - f: F, - }, - Completed, -} - -#[pin_project] -pub struct Map<Fut, F> { - #[pin] - state: MapState<Fut, F>, -} - -impl<Fut, F> Map<Fut, F> { - pub(super) fn new(future: Fut, f: F) -> Self { - Self { - state: MapState::Incomplete { future, f }, - } - } -} - -impl<'a, Fut, F, T> Future for Map<Fut, F> -where - Fut: Future, - F: FnOnce(Fut::Output) -> T, -{ - type Output = T; - - #[inline(always)] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let mut this = self.project(); - match this.state.as_mut().project() { - MapStateProj::Incomplete { future, .. } => { - let output = match future.poll(cx) { - Poll::Ready(value) => value, - Poll::Pending => return Poll::Pending, - }; - - match this.state.project_replace(MapState::Completed) { - MapStateReplace::Incomplete { f, .. } => Poll::Ready(f(output)), - _ => unreachable!(), - } - } - MapStateProj::Completed => { - panic!("Map must not be polled after it returned `Poll::Ready`") - } - } - } -} - -impl<'c, 'lt: 'c, Fut0: Ss + 'lt, F0: Ss + 'c, R0: Ss + 'c> Effective<'c> for Map<Fut0, F0> -where - F0: FnOnce(Fut0::Output) -> R0, - Fut0: Future, - Fut0::Output: 'lt, -{ - fn into_erased<B>(self) -> ErasedEffective<'c, Self::Output, Self::Effect, B> { - BoxOrReady::Boxed(Box::pin(self)) - } - - type Effect = Async; - - type Output = R0; - - type IntoFuture = Self; - - fn into_future(self) -> Self::IntoFuture { - self - } - - type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (R0, T)> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, - 'c: 'a; - - fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut 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 ()), - >, - 'c: 'a, - { - BoxOrReady::Boxed(Box::pin(async move { - let mut this = self.into_future().await; - - loop { - if let ControlFlow::Break(value) = cb(&mut this).into_future().await { - return (this, value); - } - } - })) - } - - type Map<'a, T: Ss + 'a, F: Ss + 'a> = - Map<Self, F> - where - F: FnOnce(Self::Output) -> T, - 'c: 'a; - - fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> - where - F: FnOnce(Self::Output) -> T, - 'c: 'a, - { - Map::new(self, cb) - } - - type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> - = Then<'a, Self, F, V> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'c: 'a; - - fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'c: 'a, - { - Then::new(self, cb) - } - - type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (Self::Output, T)> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'c: 'a; - - fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'c: 'a, - { - BoxOrReady::Boxed(Box::pin(async { - let mut this = self.await; - - let result = cb(&mut this).into_future().await; - - (this, result) - })) - } -} diff --git a/src/effect/async/shim.rs b/src/effect/async/shim.rs deleted file mode 100644 index 484f49b..0000000 --- a/src/effect/async/shim.rs +++ /dev/null @@ -1,116 +0,0 @@ -use core::ops::ControlFlow; - -use futures::Future; - -use crate::effect::{Effective, ErasedEffective, Ss}; - -use super::{Async, BoxOrReady, Map, Then}; - -pub struct Shim<F> { - future: F, -} - -impl<F> Shim<F> { - pub(super) fn new(future: F) -> Self { - Self { future } - } -} - -impl<'lt, U: Ss + 'lt> Effective<'lt> for Shim<U> -where - U: Future, - U::Output: Ss + 'lt, -{ - fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B> { - BoxOrReady::Boxed(Box::pin(self.future)) - } - - type Effect = Async; - - type Output = U::Output; - - type IntoFuture = U; - - fn into_future(self) -> Self::IntoFuture { - self.future - } - - type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (U::Output, T)> - 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: Ss + 'a, F: Ss + 'a>(self, mut 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, - { - BoxOrReady::Boxed(Box::pin(async move { - let mut this = self.into_future().await; - - loop { - if let ControlFlow::Break(value) = cb(&mut this).into_future().await { - return (this, value); - } - } - })) - } - - type Map<'a, T: Ss + 'a, F: Ss + 'a> - = Map<U, F> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a; - - fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a, - { - Map::new(self.future, cb) - } - - type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> - = Then<'a, U, F, V> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a; - - fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a, - { - Then::new(self.future, cb) - } - - type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (Self::Output, T)> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'lt: 'a; - - fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'lt: 'a, - { - BoxOrReady::Boxed(Box::pin(async { - let mut this = self.future.await; - - let result = cb(&mut this).into_future().await; - - (this, result) - })) - } -} diff --git a/src/effect/async/then.rs b/src/effect/async/then.rs deleted file mode 100644 index 2ffc705..0000000 --- a/src/effect/async/then.rs +++ /dev/null @@ -1,184 +0,0 @@ -use core::{ - ops::ControlFlow, - pin::Pin, - task::{Context, Poll}, -}; - -use futures::Future; -use pin_project::pin_project; - -use crate::effect::{Effective, ErasedEffective, Ss}; - -use super::{map::Map, Async, BoxOrReady}; - -#[pin_project(project = ThenStateProj, project_replace = ThenStateReplace)] -enum ThenState<'a, Fut, F, V> -where - V: Effective<'a>, -{ - Incomplete { - #[pin] - future: Fut, - f: F, - }, - Completed { - #[pin] - effective: V::IntoFuture, - }, - Temp, -} - -#[pin_project] -pub struct Then<'a, Fut, F, V> -where - V: Effective<'a>, -{ - #[pin] - state: ThenState<'a, Fut, F, V>, -} - -impl<'a, Fut, F, V> Then<'a, Fut, F, V> -where - V: Effective<'a>, -{ - pub(super) fn new(future: Fut, f: F) -> Self { - Self { - state: ThenState::Incomplete { future, f }, - } - } -} - -impl<'a, Fut, F, V> Future for Then<'a, Fut, F, V> -where - Fut: Future, - F: FnOnce(Fut::Output) -> V, - V: Effective<'a>, -{ - type Output = V::Output; - - #[inline(always)] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let mut this = self.project(); - match this.state.as_mut().project() { - ThenStateProj::Incomplete { future, .. } => { - let output = match future.poll(cx) { - Poll::Ready(value) => value, - Poll::Pending => return Poll::Pending, - }; - - match this.state.as_mut().project_replace(ThenState::Temp) { - ThenStateReplace::Incomplete { f, .. } => { - let effective = f(output).into_future(); - - this.state - .as_mut() - .project_replace(ThenState::Completed { effective }); - - match this.state.project() { - ThenStateProj::Completed { effective } => effective.poll(cx), - _ => unreachable!(), - } - } - _ => unreachable!(), - } - } - ThenStateProj::Completed { effective } => effective.poll(cx), - ThenStateProj::Temp => unreachable!(), - } - } -} - -impl<'c, 'lt: 'c, Fut0: Ss + 'lt, V0: Ss + 'lt, F0: Ss + 'c> Effective<'c> - for Then<'lt, Fut0, F0, V0> -where - F0: FnOnce(Fut0::Output) -> V0, - V0: Effective<'lt>, - Fut0: Future, - Fut0::Output: Ss + 'lt, -{ - fn into_erased<B>(self) -> ErasedEffective<'c, Self::Output, Self::Effect, B> { - BoxOrReady::Boxed(Box::pin(self)) - } - - type Effect = Async; - - type Output = V0::Output; - - type IntoFuture = Self; - - fn into_future(self) -> Self::IntoFuture { - self - } - - type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (V0::Output, T)> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'c: 'a; - - fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'c: 'a, - { - BoxOrReady::Boxed(Box::pin(async move { - let mut this = self.into_future().await; - - loop { - if let ControlFlow::Break(value) = cb(&mut this).into_future().await { - return (this, value); - } - } - })) - } - - type Map<'a, T: Ss + 'a, F: Ss + 'a> - = Map<Self, F> - where - F: FnOnce(Self::Output) -> T, - 'c: 'a; - - fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> - where - F: FnOnce(Self::Output) -> T, - 'c: 'a, - { - Map::new(self, cb) - } - - type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> - = Then<'a, Self, F, V> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'c: 'a; - - fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'c: 'a, - { - Then::new(self, cb) - } - - type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (Self::Output, T)> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'c: 'a; - - fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, - 'c: 'a, - { - BoxOrReady::Boxed(Box::pin(async { - let mut this = self.await; - - let result = cb(&mut this).into_future().await; - - (this, result) - })) - } -} diff --git a/src/effect/async/value.rs b/src/effect/async/value.rs deleted file mode 100644 index 63b2e25..0000000 --- a/src/effect/async/value.rs +++ /dev/null @@ -1,98 +0,0 @@ -use core::ops::ControlFlow; - -use crate::effect::{Effective, ErasedEffective, Ss}; - -use super::{Async, BoxOrReady}; - -pub struct Value<T>(pub T); - -impl<'lt, U: Ss + 'lt> Effective<'lt> for Value<U> { - fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B> { - BoxOrReady::Ready(self.0) - } - - type Effect = Async; - - type Output = U; - - type IntoFuture = core::future::Ready<U>; - - fn into_future(self) -> Self::IntoFuture { - core::future::ready(self.0) - } - - type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (U, T)> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'lt: 'a; - - fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> - where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, - 'lt: 'a, - { - BoxOrReady::Boxed(Box::pin(async move { - let mut this = self.into_future().await; - - loop { - if let ControlFlow::Break(value) = cb(&mut this).into_future().await { - return (this, value); - } - } - })) - } - - type Map<'a, T: Ss + 'a, F: Ss + 'a> - = Value<T> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a; - - fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> - where - F: FnOnce(Self::Output) -> T, - 'lt: 'a, - { - Value(cb(self.0)) - } - - type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> - = V - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a; - - fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> - where - F: FnOnce(Self::Output) -> V, - V: Effective<'a, Output = T, Effect = Self::Effect>, - 'lt: 'a, - { - cb(self.0) - } - - type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> - = BoxOrReady<'a, (Self::Output, T)> - where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, - 'lt: 'a; - - fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> - where - F: for<'b> FnOnce( - &'b mut Self::Output, - ) - -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, - 'lt: 'a, - { - BoxOrReady::Boxed(Box::pin(async { - let mut this = self.0; - - let result = cb(&mut this).into_future().await; - - (this, result) - })) - } -} diff --git a/src/effect/blocking.rs b/src/effect/blocking.rs index 1400c9d..bc9508d 100644 --- a/src/effect/blocking.rs +++ b/src/effect/blocking.rs @@ -142,18 +142,7 @@ impl<'lt, U: Ss + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { impl<B: BlockOn> Join for Blocking<B> { type Effect = Blocking<B>; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Value<(T0::Output, T1::Output), B> - where - T0: Effective<'a, Effect = Self::Effect>, - T1: Effective<'a, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Value<(T0::Output, T1::Output, T2::Output), B> - where - T0: Effective<'a, Effect = Self::Effect>, - T1: Effective<'a, Effect = Self::Effect>, - T2: Effective<'a, Effect = Self::Effect>; - - fn two<'a, T0, T1>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0, T1>(cb: (T0, T1)) -> Value<(T0::Output, T1::Output), B> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, @@ -164,7 +153,7 @@ impl<B: BlockOn> Join for Blocking<B> { Value((v0, v1), Default::default()) } - fn three<'a, T0, T1, T2>(cb: (T0, T1, T2)) -> Self::Three<'a, T0, T1, T2> + fn three<'a, T0, T1, T2>(cb: (T0, T1, T2)) -> Value<(T0::Output, T1::Output, T2::Output), B> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, @@ -181,18 +170,7 @@ impl<B: BlockOn> Join for Blocking<B> { impl<B: BlockOn> TryJoin for Blocking<B> { type Effect = Blocking<B>; - type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Value<Result<(T0::Ok, T1::Ok), T0::Err>, B> - where - T0: TryEffective<'a, Effect = Self::Effect>, - T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - - type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Value<Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, B> - where - 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, T0, T1, F0, F1>(cb: (F0, F1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0, T1, F0, F1>(cb: (F0, F1)) -> Value<Result<(T0::Ok, T1::Ok), T0::Err>, B> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, @@ -212,7 +190,9 @@ impl<B: BlockOn> TryJoin for Blocking<B> { Value(Ok((v0, v1)), Default::default()) } - fn three<'a, T0, T1, T2, F0, F1, F2>(cb: (F0, F1, F2)) -> Self::Three<'a, T0, T1, T2> + fn three<'a, T0, T1, T2, F0, F1, F2>( + cb: (F0, F1, F2), + ) -> Value<Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, B> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, diff --git a/src/protocol/visitor.rs b/src/protocol/visitor.rs index aac873f..e2ed85c 100644 --- a/src/protocol/visitor.rs +++ b/src/protocol/visitor.rs @@ -88,7 +88,8 @@ pub trait EffectiveVisitExt<'lt>: Effective<'lt> { ) -> ErasedEffective<'wrap, (Ctx, VisitResult<()>), Self::Effect> where Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, - F: Ss + F: 'wrap + + Ss + for<'temp> FnOnce( &'temp mut Ctx, ) @@ -121,10 +122,11 @@ pub trait EffectiveVisitExt<'lt>: Effective<'lt> { ) -> ErasedEffective<'wrap, (Ctx, VisitResult<()>), Self::Effect> where Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, - F: for<'temp> FnOnce( - &'temp mut Ctx, - ) - -> ErasedEffective<'temp, VisitResult<()>, Self::Effect, &'ctx ()>, + F: 'wrap + + for<'temp> FnOnce( + &'temp mut Ctx, + ) + -> ErasedEffective<'temp, VisitResult<()>, Self::Effect, &'ctx ()>, 'ctx: 'lt, Ctx: Ss, F: Ss, diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs index c525513..4138be1 100644 --- a/src/protocol/visitor/sequence.rs +++ b/src/protocol/visitor/sequence.rs @@ -93,10 +93,10 @@ pub fn visit_sequence<'a, 'ctx, E: Effect>( scope: DynSequenceScope<'a, 'ctx, E>, ) -> ErasedEffective<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> { if let Some(object) = visitor.0.upcast_mut::<SequenceProto<E>>() { - // Allow the visitor to give a hint if it wants. + // Allow the visitor to walk the sequence scope. object.visit(scope) } else { - // If the visitor doesn't support request hint then we continue. + // If the visitor doesn't support sequence then we continue. VisitResult::Skipped(scope).ready() } } |