-rw-r--r--src/build/builders/core/struct.rs4
-rw-r--r--src/effect.rs202
-rw-r--r--src/effect/async.rs384
-rw-r--r--src/effect/async/map.rs165
-rw-r--r--src/effect/async/shim.rs116
-rw-r--r--src/effect/async/then.rs184
-rw-r--r--src/effect/async/value.rs98
-rw-r--r--src/effect/blocking.rs32
-rw-r--r--src/protocol/visitor.rs12
-rw-r--r--src/protocol/visitor/sequence.rs4
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()
}
}