effect system put together
Konnor Andrews 2024-05-21
parent 167a1ec · commit 0fcdedf
-rw-r--r--src/any.rs72
-rw-r--r--src/build.rs6
-rw-r--r--src/build/builders/core/bool.rs14
-rw-r--r--src/build/builders/core/struct.rs65
-rw-r--r--src/effect.rs251
-rw-r--r--src/effect/async.rs434
-rw-r--r--src/effect/async/map.rs162
-rw-r--r--src/effect/async/shim.rs112
-rw-r--r--src/effect/async/then.rs187
-rw-r--r--src/effect/async/value.rs98
-rw-r--r--src/effect/blocking.rs140
-rw-r--r--src/hkt.rs42
-rw-r--r--src/lib.rs24
-rw-r--r--src/macros/build.rs26
-rw-r--r--src/protocol/visitor/recoverable.rs10
-rw-r--r--src/protocol/visitor/request_hint.rs8
-rw-r--r--src/protocol/visitor/sequence.rs12
-rw-r--r--src/protocol/visitor/tag.rs10
-rw-r--r--src/protocol/visitor/value.rs8
-rw-r--r--src/protocol/walker/hint.rs8
-rw-r--r--src/transform.rs13
-rw-r--r--src/walk.rs13
-rw-r--r--src/walk/walkers/core/key_value.rs25
-rw-r--r--src/walk/walkers/core/noop.rs6
-rw-r--r--src/walk/walkers/core/struct.rs114
-rw-r--r--src/walk/walkers/core/tag.rs12
-rw-r--r--src/walk/walkers/core/value.rs8
-rw-r--r--tests/builder_struct.rs17
28 files changed, 1171 insertions, 726 deletions
diff --git a/src/any.rs b/src/any.rs
index 78190df..9dc5115 100644
--- a/src/any.rs
+++ b/src/any.rs
@@ -3,7 +3,7 @@
//! The `AnyTrait` trait provides dynamic upcasting to trait objects.
pub mod indirect;
-// mod static_wrapper;
+mod static_wrapper;
mod type_name_id;
use crate::{
@@ -12,7 +12,7 @@ use crate::{
};
use core::marker::PhantomData;
-// pub use static_wrapper::*;
+pub use static_wrapper::*;
pub use type_name_id::*;
#[cfg(all(feature = "alloc", not(feature = "std")))]
@@ -46,50 +46,44 @@ higher_ranked_type! {
where {
T: ?Sized + TypeName::LowerType<'a, 'ctx>
};
+ }
+}
+
+pub struct MutHrt<T: ?Sized>(Marker<T>);
- impl['a, 'ctx, T] type HigherRankedAll['a, 'ctx] for &'a T =
- RefHrt<TypeName::HigherRankedAll<'a, 'ctx, T>>
+higher_ranked_type! {
+ impl TypeName {
+ impl['a, 'ctx, T] type T['a, 'ctx] for MutHrt<T> =
+ &'a mut TypeName::T<'a, 'ctx, T>
where {
- T: ?Sized + TypeName::LowerType<'a, 'ctx>
+ T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>,
+ TypeName::T<'a, 'ctx, T>: 'a
+ };
+
+ impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for &'a mut T =
+ MutHrt<TypeName::HigherRanked<'a, 'ctx, T>>
+ where {
+ T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>
};
}
}
-pub struct MutHrt<T: ?Sized>(Marker<T>);
+#[cfg(feature = "alloc")]
+higher_ranked_type! {
+ impl TypeName {
+ impl['a, 'ctx, T] type T['a, 'ctx] for Box<T> =
+ Box<TypeName::T<'a, 'ctx, T>>
+ where {
+ T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>,
+ };
-// higher_ranked_type! {
-// impl TypeName {
-// impl['a, 'ctx, T] type T['a, 'ctx] for MutHrt<T> =
-// &'a mut TypeName::T<'a, 'ctx, T>
-// where {
-// T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>,
-// TypeName::T<'a, 'ctx, T>: 'a
-// };
-//
-// impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for &'a mut T =
-// MutHrt<TypeName::HigherRanked<'a, 'ctx, T>>
-// where {
-// T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>
-// };
-// }
-// }
-
-// #[cfg(feature = "alloc")]
-// higher_ranked_type! {
-// impl TypeName {
-// impl['a, 'ctx, T] type T['a, 'ctx] for Box<T> =
-// Box<TypeName::T<'a, 'ctx, T>>
-// where {
-// T: ?Sized + TypeName::LowerForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>,
-// };
-//
-// impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for Box<T> =
-// Box<TypeName::HigherRanked<'a, 'ctx, T>>
-// where {
-// T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>
-// };
-// }
-// }
+ impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for Box<T> =
+ Box<TypeName::HigherRanked<'a, 'ctx, T>>
+ where {
+ T: ?Sized + TypeName::RaiseForLt<'a, 'ctx, TypeName::Bound<'a, 'ctx>>
+ };
+ }
+}
/// Dynamic trait lookup.
///
diff --git a/src/build.rs b/src/build.rs
index e1c62f7..3ce2b68 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -1,7 +1,7 @@
pub mod builders;
use crate::{
- effect::{Effect, ObjSafe},
+ effect::{Effect, ErasedEffective},
protocol::DynVisitor,
};
@@ -35,7 +35,7 @@ pub trait BuilderTypes {
/// - Call [`Self::build()`] to finish building the value and get any errors
/// that happened during filling it with data.
pub trait Builder<'ctx, E: Effect>: BuilderTypes + Sized + Send + Sync {
- fn from_seed<'a>(seed: Self::Seed) -> ObjSafe<'a, Self, E>
+ fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E>
where
Self: 'a;
@@ -43,7 +43,7 @@ pub trait Builder<'ctx, E: Effect>: BuilderTypes + Sized + Send + Sync {
///
/// If an error happened with the builder during the walk
/// it will be reported here.
- fn build<'a>(self) -> ObjSafe<'a, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a;
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index 26ad20d..3cb60a6 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
use crate::{
any::OwnedStatic,
any_trait,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
protocol::{
visitor::{Value, ValueProto, VisitResult},
DynVisitor,
@@ -40,19 +40,19 @@ impl<E> crate::BuilderTypes for Builder<E> {
impl<'ctx, E: Effect> crate::Builder<'ctx, E> for Builder<E> {
#[inline(always)]
- fn build<'a>(self) -> ObjSafe<'a, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
- E::ready(self.0.ok_or(Error::Incomplete)).into()
+ E::ready(self.0.ok_or(Error::Incomplete)).into_erased()
}
#[inline(always)]
- fn from_seed<'a>(_seed: Self::Seed) -> ObjSafe<'a, Self, E>
+ fn from_seed<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self, E>
where
Self: 'a,
{
- E::ready(Self(None, PhantomData)).into()
+ E::ready(Self(None, PhantomData)).into_erased()
}
#[inline(always)]
@@ -72,11 +72,11 @@ impl<'ctx, E: Effect> Value<'ctx, OwnedStatic<bool>, E> for Builder<E> {
fn visit<'a>(
&'a mut self,
OwnedStatic(value): OwnedStatic<bool>,
- ) -> ObjSafe<'a, VisitResult<OwnedStatic<bool>>, E>
+ ) -> ErasedEffective<'a, VisitResult<OwnedStatic<bool>>, E>
where
'ctx: 'a,
{
self.0 = Some(value);
- E::ready(Flow::Done.into()).into()
+ E::ready(Flow::Done.into()).into_erased()
}
}
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs
index 1b5c00a..7e8d854 100644
--- a/src/build/builders/core/struct.rs
+++ b/src/build/builders/core/struct.rs
@@ -3,7 +3,7 @@ use core::{marker::PhantomData, ops::ControlFlow};
use crate::{
any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName},
any_trait,
- effect::{Adapters, Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
hkt::Marker,
protocol::{
visitor::{
@@ -42,9 +42,11 @@ pub trait StructTypeInfo<'ctx, M, E: Effect>: 'static {
type T: Send + Sync;
- fn new_builders<'a>(seed: Self::Seed) -> ObjSafe<'a, Self::Builders, E>;
+ fn new_builders<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E>;
- fn from_builders<'a>(builders: Self::Builders) -> ObjSafe<'a, Result<Self::T, Self::Error>, E>;
+ fn from_builders<'a>(
+ builders: Self::Builders,
+ ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>;
fn as_visitor<'a>(
marker: Self::FieldMarker,
@@ -86,7 +88,7 @@ where
E: Effect,
{
#[inline(always)]
- fn from_seed<'a>(seed: Self::Seed) -> ObjSafe<'a, Self, E>
+ fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E>
where
Self: 'a,
{
@@ -99,10 +101,10 @@ where
_generics: Default::default(),
}
})
- .into()
+ .into_erased()
}
- fn build<'a>(self) -> ObjSafe<'a, Result<Self::Value, Self::Error>, E>
+ fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E>
where
Self: 'a,
{
@@ -111,7 +113,7 @@ where
Ok(value) => Ok(value),
Err(err) => Err(StructError { error: err }),
})
- .into()
+ .into_erased()
}
fn as_visitor(&mut self) -> DynVisitor<'_, 'ctx> {
@@ -134,24 +136,23 @@ where
E: Effect,
{
#[inline(always)]
- fn visit<'a>(
+ fn visit<'a: 'c, 'b: 'c, 'c>(
&'a mut self,
_kind: tags::Map,
- walker: DynWalkerObjSafe<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynWalkerObjSafe<'a, 'ctx, E>>, E> {
+ walker: DynWalkerObjSafe<'b, 'ctx, E>,
+ ) -> ErasedEffective<'c, VisitResult<DynWalkerObjSafe<'b, 'ctx, E>>, E> {
// This signals to go into map mode for the sequence.
self.mode = StructMode::Map;
- E::with(NoopVisitor::new(), |noop, _| {
- (
+ E::ready(NoopVisitor::new())
+ .as_ctx(|noop| {
walker
.walk(DynVisitor(noop))
.map(|x| x.to_continue().into())
- .into(),
- PhantomData,
- )
- })
- .into()
+ .into_erased()
+ })
+ .map(|(_, value)| value)
+ .into_erased()
}
}
@@ -165,7 +166,7 @@ where
fn visit<'a>(
&'a mut self,
scope: DynSequenceScope<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> {
+ ) -> ErasedEffective<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> {
match self.mode {
StructMode::Tuple => {
E::ready((self, scope, 0))
@@ -192,12 +193,14 @@ where
ControlFlow::Break(VisitResult::Control(Flow::Done))
}
})
- .into()
+ .into_erased()
} else {
- E::ready(ControlFlow::Break(VisitResult::Control(Flow::Done))).into()
+ E::ready(ControlFlow::Break(VisitResult::Control(Flow::Done)))
+ .into_erased()
}
})
- .into()
+ .map(|(_, value)| value)
+ .into_erased()
}
StructMode::Map => {
todo!()
@@ -268,17 +271,17 @@ any_trait! {
I: StructTypeInfo<'ctx, M, E>,
}
-impl<'b, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'b, 'ctx, I, M, E>
+impl<'d, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'ctx, I, M, E>
where
E: Effect,
I: StructTypeInfo<'ctx, M, E>,
{
#[inline(always)]
- fn visit<'a>(
+ fn visit<'a: 'c, 'b: 'c, 'c>(
&'a mut self,
_key: tags::Key,
- walker: DynWalkerObjSafe<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynWalkerObjSafe<'a, 'ctx, E>>, E> {
+ walker: DynWalkerObjSafe<'b, 'ctx, E>,
+ ) -> ErasedEffective<'c, VisitResult<DynWalkerObjSafe<'b, 'ctx, E>>, E> {
todo!()
// E::wrap(async {
// let mut visitor = NameVisitor::<I, M, E> {
@@ -320,14 +323,14 @@ where
fn visit<'a>(
&'a mut self,
OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>>,
- ) -> ObjSafe<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>>>, E>
+ ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>>>, E>
where
TypeName::T<'a, 'ctx, OwnedStatic<usize>>: Send + Sized,
'ctx: 'a,
{
self.field_marker = I::marker_from_index(index);
- E::ready(VisitResult::Control(Flow::Done)).into()
+ E::ready(VisitResult::Control(Flow::Done)).into_erased()
}
}
@@ -340,14 +343,14 @@ where
fn visit<'a>(
&'a mut self,
TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>,
- ) -> ObjSafe<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E>
+ ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E>
where
TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized,
'ctx: 'a,
{
self.field_marker = I::marker_from_name(name);
- E::ready(VisitResult::Control(Flow::Done)).into()
+ E::ready(VisitResult::Control(Flow::Done)).into_erased()
}
}
@@ -360,13 +363,13 @@ where
fn visit<'a>(
&'a mut self,
OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>,
- ) -> ObjSafe<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>>, E>
+ ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>>, E>
where
TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized,
'ctx: 'a,
{
self.field_marker = I::marker_from_name(name);
- E::ready(VisitResult::Control(Flow::Done)).into()
+ E::ready(VisitResult::Control(Flow::Done)).into_erased()
}
}
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)
+ }
}
diff --git a/src/effect/async.rs b/src/effect/async.rs
index 84aacee..ffe8bb7 100644
--- a/src/effect/async.rs
+++ b/src/effect/async.rs
@@ -1,4 +1,18 @@
-use core::pin::Pin;
+// 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;
@@ -7,7 +21,7 @@ use pin_project::pin_project;
use crate::hkt::Marker;
-use super::{Effect, Effective, ErasedForLt, Join, TryJoin};
+use super::{Effect, Effective, ErasedEffective, ErasedForLt, Join, TryJoin};
pub enum Async {}
@@ -26,13 +40,13 @@ pub enum BoxOrReady<'a, T> {
pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>;
-impl<'a, T: Send + Sync> ErasedForLt<'a, T, Async, &'a T> for ErasedHrt<T> {
+impl<'a, T: Send + Sync, O> ErasedForLt<'a, T, Async, &'a (T, O), O> for ErasedHrt<T> {
type T = BoxOrReady<'a, T>;
}
-pub struct Value<T>(pub T);
-
-pub struct Wrapped<F>(pub F);
+impl<T: Send + Sync> super::ErasedHrt<T, Async> for ErasedHrt<T> {
+ type T<B> = ErasedHrt<T>;
+}
impl Effect for Async {
type Erased<T: Send + Sync> = ErasedHrt<T>;
@@ -40,10 +54,10 @@ impl Effect for Async {
type Ready<'a, T: Send + Sync + 'a> = Value<T>;
fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> {
- todo!()
+ Value(value)
}
- type FromFuture<'a, F: Send + Sync + 'a> = Wrapped<F>
+ type FromFuture<'a, F: Send + Sync + 'a> = Shim<F>
where
F: futures::prelude::Future,
F::Output: Send + Sync + 'a;
@@ -53,12 +67,12 @@ impl Effect for Async {
F: futures::prelude::Future,
F::Output: Send + Sync + 'a,
{
- todo!()
+ Shim::new(future)
}
}
impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> {
- fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> {
+ fn into_erased<B>(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect, B> {
self
}
@@ -75,80 +89,47 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> {
}
}
- type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = futures::future::Map<ErasedFuture<'lt, U>, F>
+ type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
+ = BoxOrReady<'a, (U, T)>
where
- F: FnOnce(Self::Output) -> T,
+ F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>,
'lt: 'a;
- fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
+ fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F>
where
- F: FnOnce(Self::Output) -> T,
- 'lt: 'a
+ F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>,
+ 'lt: 'a,
{
- todo!()
- }
+ BoxOrReady::Boxed(Box::pin(async move {
+ let mut this = self.into_future().await;
- type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Then<ErasedFuture<'lt, U>, V::IntoFuture, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect>;
-
- fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
- self,
- cb: F,
- ) -> Self::Then<'a, T, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect> {
- todo!()
+ loop {
+ if let ControlFlow::Break(value) = cb(&mut this).into_future().await {
+ return (this, value);
+ }
+ }
+ }))
}
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = BoxedFuture<'a, T>
+ type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Map<ErasedFuture<'lt, U>, F>
where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
+ F: FnOnce(Self::Output) -> T,
'lt: 'a;
- fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'lt: 'a {
- todo!()
- }
-}
-
-impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> {
- fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> {
- todo!()
- }
-
- type Effect = Async;
-
- type Output = U;
-
- type IntoFuture = core::future::Ready<U>;
-
- fn into_future(self) -> Self::IntoFuture {
- core::future::ready(self.0)
- }
-
- type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = core::future::Ready<T>
- where
- F: FnOnce(Self::Output) -> T;
-
fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
where
- F: FnOnce(Self::Output) -> T {
- todo!()
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a,
+ {
+ Map::new(self.into_future(), cb)
}
type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
- = V
+ = Then<'a, ErasedFuture<'lt, U>, F, V>
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,
@@ -156,81 +137,30 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> {
) -> Self::Then<'a, T, V, F>
where
F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect> {
- todo!()
+ V: Effective<'a, Output = T, Effect = Self::Effect>,
+ 'lt: 'a,
+ {
+ Then::new(self.into_future(), cb)
}
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = BoxedFuture<'a, T>
+ type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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<'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) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'lt: 'a {
- todo!()
- }
-}
-
-impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Wrapped<U>
-where
- U: Future,
- U::Output: Send + Sync + 'lt
-{
- fn into_erased(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect> {
- todo!()
- }
-
- type Effect = Async;
-
- type Output = U::Output;
-
- type IntoFuture = U;
-
- fn into_future(self) -> Self::IntoFuture {
- todo!()
- }
+ 'lt: 'a,
+ {
+ BoxOrReady::Boxed(Box::pin(async {
+ let mut this = self.into_future().await;
- type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Map<U, F>
- where
- F: FnOnce(Self::Output) -> T;
+ let result = cb(&mut this).into_future().await;
- fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
- where
- F: FnOnce(Self::Output) -> T {
- todo!()
- }
-
- type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Then<U, V::IntoFuture, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect>;
-
- fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
- self,
- cb: F,
- ) -> Self::Then<'a, T, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect> {
- todo!()
- }
-
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = BoxedFuture<'a, T>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'lt: 'a;
-
- fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'lt: 'a {
- todo!()
+ (this, result)
+ }))
}
}
@@ -238,255 +168,119 @@ impl Join for Async {
type Effect = Self;
type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>
- = futures::future::Join<ErasedFuture<'a, T0>, ErasedFuture<'a, T1>>
+ = 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: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = futures::future::Join3<ErasedFuture<'a, T0>, ErasedFuture<'a, T1>, ErasedFuture<'a, T2>, >
+ type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + '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: Send + Sync + 'a,
- T1: Send + Sync + 'a,
- F0: Send + Sync + 'a,
- F1: Send + Sync + 'a,
- >(
- cb: (F0, F1),
- ) -> Self::Two<'a, T0, T1>
+ fn two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1>
where
T0: super::Effective<'a, Effect = Self::Effect>,
T1: super::Effective<'a, Effect = Self::Effect>,
- F0: FnOnce() -> T0,
- F1: FnOnce() -> T1 {
- todo!()
+ {
+ Shim::new(futures::future::join(
+ cb.0.into_future(),
+ cb.1.into_future(),
+ ))
}
- 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>(
+ cb: (T0, T1, T2),
) -> Self::Three<'a, T0, T1, T2>
where
T0: super::Effective<'a, Effect = Self::Effect>,
T1: super::Effective<'a, Effect = Self::Effect>,
T2: super::Effective<'a, Effect = Self::Effect>,
- F0: FnOnce() -> T0,
- F1: FnOnce() -> T1,
- F2: FnOnce() -> T2 {
- todo!()
+ {
+ Shim::new(futures::future::join3(
+ cb.0.into_future(),
+ cb.1.into_future(),
+ cb.2.into_future(),
+ ))
}
}
impl TryJoin for Async {
type Effect = Self;
- type Two<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>
- = futures::future::TryJoin<ErasedFuture<'a, Result<T0, Err>>, ErasedFuture<'a, Result<T1, Err>>>
+ type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>
+ = Shim<futures::future::TryJoin<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>>>
where
- V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>,
- V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>;
+ T0: super::TryEffective<'a, Effect = Self::Effect>,
+ T1: super::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>
- = futures::future::TryJoin3<ErasedFuture<'a, Result<T0, Err>>, ErasedFuture<'a, Result<T1, Err>>, ErasedFuture<'a, Result<T1, Err>>>
+ type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>
+ = Shim<futures::future::TryJoin3<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>, BoxedFuture<'a, T2::Output>>>
where
- V0: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>,
- V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>,
- V2: super::Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>;
+ 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,
- 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: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>,
- V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>,
- F0: FnOnce() -> V0,
- F1: FnOnce() -> V1 {
- todo!()
+ T0: super::TryEffective<'a, Effect = Self::Effect>,
+ T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>,
+ F0: FnOnce() -> T0,
+ F1: FnOnce() -> T1,
+ {
+ Shim::new(futures::future::try_join(
+ Box::pin(async { cb.0().into_future().await }),
+ Box::pin(async { cb.1().into_future().await }),
+ ))
}
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: super::Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>,
- V1: super::Effective<'a, Output = Result<T1, Err>, Effect = Self::Effect>,
- V2: super::Effective<'a, Output = Result<T2, Err>, Effect = Self::Effect>,
- F0: FnOnce() -> V0,
- F1: FnOnce() -> V1,
- F2: FnOnce() -> V2 {
- todo!()
+ 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,
+ {
+ 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;
- fn poll(self: Pin<&mut Self>, cx: &mut core::task::Context<'_>) -> core::task::Poll<Self::Output> {
+ 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),
}
}
}
-
-impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, F0: Send + Sync + 'c, R0: Send + Sync + 'c> Effective<'c> for futures::future::Map<Fut0, F0>
-where
- F0: FnOnce(Fut0::Output) -> R0,
- Fut0: Future,
- Fut0::Output: 'lt,
-{
- fn into_erased(self) -> super::ErasedEffective<'c, Self::Output, Self::Effect> {
- todo!()
- }
-
- type Effect = Async;
-
- type Output = R0;
-
- type IntoFuture = Self;
-
- fn into_future(self) -> Self::IntoFuture {
- self
- }
-
- type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> =
- futures::future::Map<Self, F>
- where
- F: FnOnce(Self::Output) -> T,
- 'c: 'a;
-
- fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
- where
- F: FnOnce(Self::Output) -> T,
- 'c: 'a
- {
- todo!()
- }
-
- type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Then<Self, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect>;
-
- fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
- self,
- cb: F,
- ) -> Self::Then<'a, T, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect> {
- todo!()
- }
-
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = BoxOrReady<'a, T>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'a: 'a;
-
- fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'a: 'a {
- todo!()
- }
-}
-
-impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, V0: Send + Sync + 'lt, Fut1: Send + Sync + 'lt, F0: Send + Sync + 'c> Effective<'c> for futures::future::Then<Fut0, Fut1, F0>
-where
- F0: FnOnce(Fut0::Output) -> V0,
- V0: Effective<'lt, Effect = Async, IntoFuture = Fut1>,
- Fut1: Future,
- Fut1::Output: Send + Sync + 'lt,
- Fut0: Future,
- Fut0::Output: Send + Sync + 'lt,
-{
- fn into_erased(self) -> super::ErasedEffective<'c, Self::Output, Self::Effect> {
- todo!()
- }
-
- type Effect = Async;
-
- type Output = Fut1::Output;
-
- type IntoFuture = Self;
-
- fn into_future(self) -> Self::IntoFuture {
- todo!()
- }
-
- type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Map<Self, F>
- where
- F: FnOnce(Self::Output) -> T,
- 'c: 'a;
-
- fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
- where
- F: FnOnce(Self::Output) -> T,
- 'c: 'a {
- todo!()
- }
-
- type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
- = futures::future::Then<Self, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect>;
-
- fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
- self,
- cb: F,
- ) -> Self::Then<'a, T, V, F>
- where
- F: FnOnce(Self::Output) -> V,
- V: Effective<'a, Output = T, Effect = Self::Effect> {
- todo!()
- }
-
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
- = BoxOrReady<'a, T>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'c: 'a;
-
- fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F>
- where
- F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>,
- 'c: 'a {
- todo!()
- }
-}
diff --git a/src/effect/async/map.rs b/src/effect/async/map.rs
new file mode 100644
index 0000000..d8c1331
--- /dev/null
+++ b/src/effect/async/map.rs
@@ -0,0 +1,162 @@
+use core::{
+ ops::ControlFlow,
+ pin::Pin,
+ task::{Context, Poll},
+};
+
+use futures::Future;
+use pin_project::pin_project;
+
+use crate::effect::{Effective, ErasedEffective};
+
+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: Send + Sync + 'lt, F0: Send + Sync + 'c, R0: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + 'a> =
+ Map<Self, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'c: 'a;
+
+ fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'c: 'a,
+ {
+ Map::new(self, cb)
+ }
+
+ type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
+ self,
+ cb: F,
+ ) -> Self::Then<'a, T, V, F>
+ where
+ F: FnOnce(Self::Output) -> V,
+ V: Effective<'a, Output = T, Effect = Self::Effect>,
+ 'c: 'a,
+ {
+ Then::new(self, cb)
+ }
+
+ type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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: 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>,
+ '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
new file mode 100644
index 0000000..fcc16ae
--- /dev/null
+++ b/src/effect/async/shim.rs
@@ -0,0 +1,112 @@
+use core::ops::ControlFlow;
+
+use futures::Future;
+
+use crate::effect::{Effective, ErasedEffective};
+
+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: Send + Sync + 'lt> Effective<'lt> for Shim<U>
+where
+ U: Future,
+ U::Output: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + 'a>
+ = Map<U, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a;
+
+ fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a,
+ {
+ Map::new(self.future, cb)
+ }
+
+ type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
+ self,
+ cb: F,
+ ) -> Self::Then<'a, T, V, F>
+ where
+ F: FnOnce(Self::Output) -> V,
+ V: Effective<'a, Output = T, Effect = Self::Effect>,
+ 'lt: 'a,
+ {
+ Then::new(self.future, cb)
+ }
+
+ type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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: 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>,
+ '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
new file mode 100644
index 0000000..96b2c8c
--- /dev/null
+++ b/src/effect/async/then.rs
@@ -0,0 +1,187 @@
+use core::{
+ ops::ControlFlow,
+ pin::Pin,
+ task::{Context, Poll},
+};
+
+use futures::Future;
+use pin_project::pin_project;
+
+use crate::effect::{Effective, ErasedEffective};
+
+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: Send + Sync + 'lt, V0: Send + Sync + 'lt, F0: Send + Sync + 'c>
+ Effective<'c> for Then<'lt, Fut0, F0, V0>
+where
+ F0: FnOnce(Fut0::Output) -> V0,
+ V0: Effective<'lt>,
+ Fut0: Future,
+ Fut0::Output: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + 'a>
+ = Map<Self, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'c: 'a;
+
+ fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'c: 'a,
+ {
+ Map::new(self, cb)
+ }
+
+ type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>(
+ self,
+ cb: F,
+ ) -> Self::Then<'a, T, V, F>
+ where
+ F: FnOnce(Self::Output) -> V,
+ V: Effective<'a, Output = T, Effect = Self::Effect>,
+ 'c: 'a,
+ {
+ Then::new(self, cb)
+ }
+
+ type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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: 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>,
+ '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
new file mode 100644
index 0000000..c3a80ca
--- /dev/null
+++ b/src/effect/async/value.rs
@@ -0,0 +1,98 @@
+use core::ops::ControlFlow;
+
+use crate::effect::{Effective, ErasedEffective};
+
+use super::{Async, BoxOrReady};
+
+pub struct Value<T>(pub T);
+
+impl<'lt, U: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + '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: Send + Sync + 'a, F: Send + Sync + 'a>
+ = Value<T>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a;
+
+ fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
+ where
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a,
+ {
+ Value(cb(self.0))
+ }
+
+ type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
+ = V
+ where
+ F: FnOnce(Self::Output) -> V,
+ 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,
+ 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: Send + Sync + 'a, F: Send + Sync + '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: 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, (&'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 abadfb2..661fd12 100644
--- a/src/effect/blocking.rs
+++ b/src/effect/blocking.rs
@@ -18,10 +18,14 @@ pub struct Blocking<B>(Marker<B>);
#[repr(transparent)]
pub struct Value<T, B>(pub T, Marker<B>);
-impl<'lt, T: Send + Sync, B: BlockOn> ErasedForLt<'lt, T, Blocking<B>, &'lt T> for Value<T, B> {
+impl<'lt, T: Send + Sync, B: BlockOn, O> ErasedForLt<'lt, T, Blocking<B>, &'lt (T, O), O> for Value<T, B> {
type T = Value<T, B>;
}
+impl<T: Send + Sync, B: BlockOn> ErasedHrt<T, Blocking<B>> for Value<T, B> {
+ type T<O> = Self;
+}
+
impl<B: BlockOn> Effect for Blocking<B> {
type Erased<T: Send + Sync> = Value<T, B>;
@@ -46,7 +50,7 @@ impl<B: BlockOn> Effect for Blocking<B> {
}
impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> {
- fn into_erased(self) -> ErasedEffective<'lt, Self::Output, Self::Effect> {
+ fn into_erased<X>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, X> {
self
}
@@ -60,13 +64,35 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> {
core::future::ready(self.0)
}
+ type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
+ = Value<(U, T), B>
+ where
+ F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>,
+ 'lt: 'a;
+
+ fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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,
+ {
+ let mut this = self.0;
+
+ loop {
+ if let ControlFlow::Break(value) = cb(&mut this).0 {
+ return Value((this, value), Default::default());
+ }
+ }
+ }
+
type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B>
where
- F: FnOnce(Self::Output) -> T;
+ F: FnOnce(Self::Output) -> T,
+ 'lt: 'a;
fn map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::Map<'a, T, F>
where
F: FnOnce(Self::Output) -> T,
+ 'lt: 'a,
{
Value(cb(self.0), Default::default())
}
@@ -74,7 +100,8 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> {
type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B>
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,
@@ -83,18 +110,19 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> {
where
F: FnOnce(Self::Output) -> V,
V: Effective<'a, Output = T, Effect = Self::Effect>,
+ 'lt: 'a,
{
- cb(self.0).into_erased()
+ cb(self.0).into_erased::<()>()
}
- type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<(U, T), B>
+ type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<(U, T), B>
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,
{
let mut this = self.0;
@@ -117,49 +145,28 @@ impl<B: BlockOn> Join for Blocking<B> {
T1: Effective<'a, Effect = Self::Effect>,
T2: Effective<'a, Effect = Self::Effect>;
- fn two<
- 'a,
- T0: Send + Sync + 'a,
- T1: Send + Sync + 'a,
- F0: Send + Sync + 'a,
- F1: Send + Sync + 'a,
- >(
- cb: (F0, F1),
- ) -> Self::Two<'a, T0, T1>
+ fn two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>(cb: (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,
{
- let v0 = (cb.0)().into_erased().0;
- let v1 = (cb.1)().into_erased().0;
+ let v0 = cb.0.into_erased::<()>().0;
+ let v1 = cb.1.into_erased::<()>().0;
Value((v0, v1), Default::default())
}
- 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,
- >(
- cb: (F0, F1, F2),
+ fn three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>(
+ cb: (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,
{
- let v0 = (cb.0)().into_erased().0;
- let v1 = (cb.1)().into_erased().0;
- let v2 = (cb.2)().into_erased().0;
+ let v0 = cb.0.into_erased::<()>().0;
+ let v1 = cb.1.into_erased::<()>().0;
+ let v2 = cb.2.into_erased::<()>().0;
Value((v0, v1, v2), Default::default())
}
@@ -168,41 +175,38 @@ impl<B: BlockOn> Join for Blocking<B> {
impl<B: BlockOn> TryJoin for Blocking<B> {
type Effect = Blocking<B>;
- type Two<'a, Err: Send + Sync + 'a, V0: Send + Sync + 'a, V1: Send + Sync + 'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<Result<(T0, T1), Err>, B>
+ type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<Result<(T0::Ok, T1::Ok), T0::Err>, B>
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> = Value<Result<(T0, T1, T2), Err>, B>
+ type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, B>
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,
{
- let v0 = match (cb.0)().into_erased().0 {
+ let v0 = match (cb.0)().into_erased::<()>().0 {
Ok(v) => v,
Err(err) => return Value(Err(err), Default::default()),
};
- let v1 = match (cb.1)().into_erased().0 {
+ let v1 = match (cb.1)().into_erased::<()>().0 {
Ok(v) => v,
Err(err) => return Value(Err(err), Default::default()),
};
@@ -212,38 +216,34 @@ impl<B: BlockOn> TryJoin for Blocking<B> {
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>
- 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,
+ ) -> Self::Three<'a, T0, T1, T2>
+ 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>,
+ F0: FnOnce() -> T0,
+ F1: FnOnce() -> T1,
+ F2: FnOnce() -> T2,
{
- let v0 = match (cb.0)().into_erased().0 {
+ let v0 = match (cb.0)().into_erased::<()>().0 {
Ok(v) => v,
Err(err) => return Value(Err(err), Default::default()),
};
- let v1 = match (cb.1)().into_erased().0 {
+ let v1 = match (cb.1)().into_erased::<()>().0 {
Ok(v) => v,
Err(err) => return Value(Err(err), Default::default()),
};
- let v2 = match (cb.2)().into_erased().0 {
+ let v2 = match (cb.2)().into_erased::<()>().0 {
Ok(v) => v,
Err(err) => return Value(Err(err), Default::default()),
};
diff --git a/src/hkt.rs b/src/hkt.rs
index faac1af..58f8501 100644
--- a/src/hkt.rs
+++ b/src/hkt.rs
@@ -70,11 +70,11 @@ macro_rules! higher_ranked_trait {
$($($lower_where)*)?
$($($higher_where)*)?
{
- type T: RaiseForLt<$($lt,)+ $($($generic)*,)? B, HigherRanked = Self, HigherRankedAll = Self> + ?Sized + $($lower)*;
+ type T: RaiseForLt<$($lt,)+ $($($generic)*,)? B, HigherRanked = Self> + ?Sized + $($lower)*;
}
pub trait RaiseForLt<$($lt,)+ $($($generic)*,)? B>
- : RaiseForLtAll<$($($generic)*,)? B>
+ // : RaiseForLtAll<$($($generic)*,)? B>
where
$($($lower_where)*)?
$($($higher_where)*)?
@@ -82,12 +82,12 @@ macro_rules! higher_ranked_trait {
type HigherRanked: LowerForLt<$($lt,)+ $($($generic)*,)? B, T = Self> + ?Sized + $($higher)*;
}
- pub trait RaiseForLtAll<$($($generic)*,)? B>
- where
- $($($higher_where)*)?
- {
- type HigherRankedAll: for<$($lt,)+> LowerForLt<$($lt,)+ $($($generic)*,)? $bound> + ?Sized + $($higher)*;
- }
+ // pub trait RaiseForLtAll<$($($generic)*,)? B>
+ // where
+ // $($($higher_where)*)?
+ // {
+ // type HigherRankedAll: for<$($lt,)+> LowerForLt<$($lt,)+ $($($generic)*,)? $bound> + ?Sized + $($higher)*;
+ // }
pub type Bound<$($lt,)+ $($($generic)*)?> = $bound;
@@ -121,9 +121,9 @@ macro_rules! higher_ranked_trait {
pub type HigherRanked<$($lt,)+ $($($generic)*,)? __> =
<__ as RaiseForLt<$($lt,)+ $($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRanked;
-
- pub type HigherRankedAll<$($lt,)+ $($($generic)*,)? __> =
- <__ as RaiseForLtAll<$($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRankedAll;
+ //
+ // pub type HigherRankedAll<$($lt,)+ $($($generic)*,)? __> =
+ // <__ as RaiseForLtAll<$($($generic)*,)? Bound<$($lt,)+ $($($generic)*)?>>>::HigherRankedAll;
}
}
}
@@ -141,10 +141,10 @@ macro_rules! higher_ranked_type {
impl$([$($higher_generic:tt)*])? type HigherRanked[$($higher_lt:lifetime),+]$([$($higher_forward:tt)*])? for $higher_lower:ty =
$higher:ty
$(where {$($higher_where:tt)*})?;
-
- impl$([$($higher_all_generic:tt)*])? type HigherRankedAll[$($higher_all_lt:lifetime),+]$([$($higher_all_forward:tt)*])? for $higher_all_lower:ty =
- $higher_all:ty
- $(where {$($higher_all_where:tt)*})?;
+ //
+ // impl$([$($higher_all_generic:tt)*])? type HigherRankedAll[$($higher_all_lt:lifetime),+]$([$($higher_all_forward:tt)*])? for $higher_all_lower:ty =
+ // $higher_all:ty
+ // $(where {$($higher_all_where:tt)*})?;
}
} => {
impl$(<$($lower_generic)*>)* $higher_trait::LowerForLt<$($lower_forward)*, $higher_trait::Bound<$($lower_forward)*>> for $lower_higher
@@ -158,12 +158,12 @@ macro_rules! higher_ranked_type {
{
type HigherRanked = $higher;
}
-
- impl$(<$($higher_all_generic)*>)* $higher_trait::RaiseForLtAll<$($($higher_all_forward)*,)? $higher_trait::Bound<$($higher_all_lt,)+ $($($higher_all_forward)*)?>> for $higher_all_lower
- $(where $($higher_all_where)*)?
- {
- type HigherRankedAll = $higher_all;
- }
+ //
+ // impl$(<$($higher_all_generic)*>)* $higher_trait::RaiseForLtAll<$($($higher_all_forward)*,)? $higher_trait::Bound<$($higher_all_lt,)+ $($($higher_all_forward)*)?>> for $higher_all_lower
+ // $(where $($higher_all_where)*)?
+ // {
+ // type HigherRankedAll = $higher_all;
+ // }
}
}
pub use higher_ranked_type;
diff --git a/src/lib.rs b/src/lib.rs
index c103de6..e9627c5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,18 +8,18 @@
extern crate alloc;
pub mod any;
-// mod build;
+mod build;
pub mod effect;
pub mod hkt;
-// pub mod macros;
-// pub mod protocol;
+pub mod macros;
+pub mod protocol;
pub mod symbol;
-// mod transform;
-// mod walk;
+mod transform;
+mod walk;
-// pub use build::*;
-// pub use transform::*;
-// pub use walk::*;
+pub use build::*;
+pub use transform::*;
+pub use walk::*;
use symbol::Symbol;
@@ -130,14 +130,14 @@ macro_rules! Walk {
index: usize,
value: &'ctx Self::T,
visitor: $crate::protocol::DynVisitor<'a, 'ctx>,
- ) -> $crate::effect::ObjSafe<'a, Result<$crate::Flow, Self::FieldError>, E> {
+ ) -> $crate::effect::ErasedEffective<'a, Result<$crate::Flow, Self::FieldError>, E> {
mod fields {
enum Fields {$($field),*}
$(pub const $field: usize = Fields::$field as usize;)*
}
- use $crate::effect::Adapters;
+ use $crate::effect::Effective;
match index {
$(fields::$field => {
@@ -154,7 +154,7 @@ macro_rules! Walk {
Err(err) => {
Err(FieldError(FieldErrorKind::$field(err)))
}
- }).into()
+ }).into_erased()
// E::map($crate::Walker::<'ctx, E>::walk(walker, visitor), |result| match result {
// Ok(_) => {
@@ -165,7 +165,7 @@ macro_rules! Walk {
// }
// })
})*
- _ => E::ready(Ok($crate::Flow::Done)).into()
+ _ => E::ready(Ok($crate::Flow::Done)).into_erased()
}
}
}
diff --git a/src/macros/build.rs b/src/macros/build.rs
index 2a45c0a..380063b 100644
--- a/src/macros/build.rs
+++ b/src/macros/build.rs
@@ -1,4 +1,4 @@
-use crate::{effect::Blocking, transform, DefaultMode};
+use crate::{effect::blocking::Blocking, transform, DefaultMode};
#[macro_export]
macro_rules! Build {
@@ -45,18 +45,18 @@ macro_rules! Build {
type Seed = ($(<$type as $crate::BuilderTypes>::Seed),*);
#[inline(always)]
- fn new_builders<'a>(seed: Self::Seed) -> $crate::effect::ObjSafe<'a, Self::Builders, E> {
+ fn new_builders<'a>(seed: Self::Seed) -> $crate::effect::ErasedEffective<'a, Self::Builders, E> {
let ($($field),*) = seed;
- use $crate::effect::Adapters;
+ use $crate::effect::Effective;
- E::join(
- $crate::effect::Join(($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)*), $crate::hkt::Marker::default())
+ $crate::effect::join(
+ ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)*)
).map(|($($field,)*)| {
Builders {
$($field),*
}
- }).into()
+ }).into_erased()
// E::wrap(async move {
// Builders {
@@ -65,20 +65,20 @@ macro_rules! Build {
// })
}
- fn from_builders<'a>(builders: Self::Builders) -> $crate::effect::ObjSafe<'a, Result<Self::T, Self::Error>, E> {
+ fn from_builders<'a>(builders: Self::Builders) -> $crate::effect::ErasedEffective<'a, Result<Self::T, Self::Error>, E> {
use $crate::Builder;
- use $crate::effect::Adapters;
+ use $crate::effect::Effective;
- E::try_join(
- $crate::effect::Join((
- $(builders.$field.build().map(|x| x.map_err(Error::$field)).into(),)*
- ), $crate::hkt::Marker::default())
+ $crate::effect::try_join(
+ (
+ $(|| builders.$field.build().map(|x| x.map_err(Error::$field)),)*
+ )
).map(|result| match result {
Ok(($($field,)*)) => Ok($name {
$($field),*
}),
Err(err) => Err(err)
- }).into()
+ }).into_erased()
// E::wrap(async {
// Ok($name {
diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs
index 6f76d92..7a2b455 100644
--- a/src/protocol/visitor/recoverable.rs
+++ b/src/protocol/visitor/recoverable.rs
@@ -1,6 +1,6 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
higher_ranked_type,
hkt::Marker,
protocol::{
@@ -16,7 +16,7 @@ pub trait Recoverable<'ctx, E: Effect> {
fn visit<'a>(
&'a mut self,
scope: DynRecoverableScope<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E>;
+ ) -> ErasedEffective<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E>;
}
pub struct RecoverableProto<E: Effect>(Marker<E>);
@@ -41,7 +41,7 @@ pub trait RecoverableScope<'ctx, E: Effect> {
fn new_walk<'this: 'effect, 'visitor: 'effect, 'effect>(
&'this mut self,
visitor: DynVisitor<'visitor, 'ctx>,
- ) -> ObjSafe<'effect, Status, E>;
+ ) -> ErasedEffective<'effect, Status, E>;
}
pub type DynRecoverableScope<'a, 'ctx, E> =
@@ -70,12 +70,12 @@ impl<E: Effect> HintMeta for RecoverableProto<E> {
pub fn visit_recoverable<'a, 'ctx, E: Effect>(
visitor: DynVisitor<'a, 'ctx>,
scope: DynRecoverableScope<'a, 'ctx, E>,
-) -> ObjSafe<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E> {
+) -> ErasedEffective<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E> {
if let Some(object) = visitor.0.upcast_mut::<RecoverableProto<E>>() {
// Allow the visitor to give a hint if it wants.
object.visit(scope)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(VisitResult::Skipped(scope)).into()
+ E::ready(VisitResult::Skipped(scope)).into_erased()
}
}
diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs
index e8c4d6d..f60005e 100644
--- a/src/protocol/visitor/request_hint.rs
+++ b/src/protocol/visitor/request_hint.rs
@@ -1,6 +1,6 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
higher_ranked_type,
hkt::Marker,
protocol::{DynVisitor, DynWalker},
@@ -17,7 +17,7 @@ pub trait RequestHint<'ctx, E: Effect> {
fn request_hint<'a>(
&'a mut self,
walker: DynWalker<'a, 'ctx>,
- ) -> ObjSafe<'a, VisitResult<DynWalker<'a, 'ctx>>, E>;
+ ) -> ErasedEffective<'a, VisitResult<DynWalker<'a, 'ctx>>, E>;
}
pub struct RequestHintProto<E: Effect>(Marker<E>);
@@ -48,12 +48,12 @@ higher_ranked_type! {
pub fn visit_request_hint<'a, 'ctx, E: Effect>(
visitor: DynVisitor<'a, 'ctx>,
walker: DynWalker<'a, 'ctx>,
-) -> ObjSafe<'a, VisitResult<DynWalker<'a, 'ctx>>, E> {
+) -> ErasedEffective<'a, VisitResult<DynWalker<'a, 'ctx>>, E> {
if let Some(object) = visitor.0.upcast_mut::<RequestHintProto<E>>() {
// Allow the visitor to give a hint if it wants.
object.request_hint(walker)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(VisitResult::Skipped(walker)).into()
+ E::ready(VisitResult::Skipped(walker)).into_erased()
}
}
diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs
index 1f2458f..4f18f49 100644
--- a/src/protocol/visitor/sequence.rs
+++ b/src/protocol/visitor/sequence.rs
@@ -1,6 +1,6 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
higher_ranked_type,
hkt::Marker,
protocol::{
@@ -20,7 +20,7 @@ pub trait Sequence<'ctx, E: Effect> {
fn visit<'a>(
&'a mut self,
scope: DynSequenceScope<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E>;
+ ) -> ErasedEffective<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E>;
}
pub struct SequenceProto<E: Effect>(Marker<E>);
@@ -42,9 +42,9 @@ higher_ranked_type! {
}
pub trait SequenceScope<'ctx, E: Effect> {
- fn size_hint(&mut self) -> ObjSafe<'_, (usize, Option<usize>), E>;
+ fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E>;
- fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ObjSafe<'a, Flow, E>;
+ fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ErasedEffective<'a, Flow, E>;
}
pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + Send + Sync + 'a);
@@ -90,12 +90,12 @@ impl<E: Effect> HintMeta for SequenceProto<E> {
pub fn visit_sequence<'a, 'ctx, E: Effect>(
visitor: DynVisitor<'a, 'ctx>,
scope: DynSequenceScope<'a, 'ctx, E>,
-) -> ObjSafe<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, 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.
object.visit(scope)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(VisitResult::Skipped(scope)).into()
+ E::ready(VisitResult::Skipped(scope)).into_erased()
}
}
diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs
index 2c947b5..61ac4b7 100644
--- a/src/protocol/visitor/tag.rs
+++ b/src/protocol/visitor/tag.rs
@@ -1,6 +1,6 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
higher_ranked_type,
hkt::Marker,
protocol::{
@@ -45,11 +45,11 @@ impl TagKind for TagDyn {
}
pub trait Tag<'ctx, K: TagKind, E: Effect> {
- fn visit<'a>(
+ fn visit<'a: 'c, 'b: 'c, 'c>(
&'a mut self,
kind: K,
- walker: DynWalkerObjSafe<'a, 'ctx, E>,
- ) -> ObjSafe<'a, VisitResult<DynWalkerObjSafe<'a, 'ctx, E>>, E>;
+ walker: DynWalkerObjSafe<'b, 'ctx, E>,
+ ) -> ErasedEffective<'c, VisitResult<DynWalkerObjSafe<'b, 'ctx, E>>, E>;
}
pub struct TagProto<K: TagKind, E: Effect>(Marker<(K, E)>);
@@ -169,7 +169,7 @@ pub fn visit_tag<'a, 'ctx: 'a, K: TagKind, E: Effect, W: crate::Walker<'ctx, E>
kind: K,
mut visitor: DynVisitor<'a, 'ctx>,
walker: W,
-) -> ObjSafe<'a, Result<VisitResult<W>, TagError<W::Error>>, E>
+) -> ErasedEffective<'a, Result<VisitResult<W>, TagError<W::Error>>, E>
where
W: WalkerTypes,
{
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 9b4c65e..11c78ff 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -4,7 +4,7 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
higher_ranked_type,
hkt::Marker,
protocol::{
@@ -31,7 +31,7 @@ pub trait Value<'ctx, T: ?Sized + TypeName::MemberType, E: Effect> {
fn visit<'a>(
&'a mut self,
value: TypeName::T<'a, 'ctx, T>,
- ) -> ObjSafe<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E>
+ ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E>
where
TypeName::T<'a, 'ctx, T>: Send + Sized,
'ctx: 'a;
@@ -96,7 +96,7 @@ impl<T: TypeName::MemberType, E: Effect> HintMeta for ValueProto<T, E> {
pub fn visit_value<'a, 'ctx, T: Send + TypeName::LowerType<'a, 'ctx>, E: Effect>(
visitor: DynVisitor<'a, 'ctx>,
value: T,
-) -> ObjSafe<'a, VisitResult<T>, E>
+) -> ErasedEffective<'a, VisitResult<T>, E>
where
TypeName::HigherRanked<'a, 'ctx, T>: TypeName::MemberType,
{
@@ -108,6 +108,6 @@ where
object.visit(value)
} else {
// If the visitor doesn't support request hint then we continue.
- E::ready(VisitResult::Skipped(value)).into()
+ E::ready(VisitResult::Skipped(value)).into_erased()
}
}
diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs
index a580ab0..8707923 100644
--- a/src/protocol/walker/hint.rs
+++ b/src/protocol/walker/hint.rs
@@ -6,7 +6,7 @@
use crate::{
any::TypeName,
- effect::{Effect, ObjSafe},
+ effect::{Effect, ErasedEffective},
higher_ranked_trait, higher_ranked_type,
hkt::Marker,
protocol::DynVisitor,
@@ -17,7 +17,7 @@ higher_ranked_trait! {
pub type class Meta for<'a, 'ctx> {
type Bound = &'a &'ctx ();
- type T: { Send + Sized } where { 'ctx: 'a };
+ type T: { Send + Sync + Sized } where { 'ctx: 'a };
type HigherRanked: { };
}
@@ -58,13 +58,13 @@ pub trait Hint<'ctx, Protocol: ?Sized + HintMeta> {
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
hint: MetaHint<'a, 'ctx, Protocol>,
- ) -> ObjSafe<'a, Flow, Protocol::Effect>;
+ ) -> ErasedEffective<'a, Flow, Protocol::Effect>;
/// Ask the walker for information about it's support of the protocol.
fn known<'a>(
&'a mut self,
hint: &'a MetaHint<'a, 'ctx, Protocol>,
- ) -> ObjSafe<'a, Result<MetaKnown<'a, 'ctx, Protocol>, ()>, Protocol::Effect>;
+ ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, Protocol>, ()>, Protocol::Effect>;
}
pub struct HintProto<Protocol: ?Sized>(Marker<Protocol>);
diff --git a/src/transform.rs b/src/transform.rs
index 9f92ba2..4652b9b 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -2,7 +2,7 @@ use core::marker::PhantomData;
use crate::{
build::Builder,
- effect::{Adapters, Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
hkt::Marker,
Walk, Walker, WalkerTypes,
};
@@ -12,19 +12,18 @@ use crate::{
pub fn transform<'a, 'ctx: 'a, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: Effect>(
seed: B::Seed,
walker: W,
-) -> ObjSafe<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> {
+) -> ErasedEffective<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> {
B::from_seed(seed)
- .as_ctx_for(
+ .as_ctx(
#[inline(always)]
- move |builder, _| (walker.walk(builder.as_visitor()), PhantomData),
+ move |builder| walker.walk(builder.as_visitor()).into_erased(),
)
- .then(|(builder, walker_result), _| {
+ .then(|(builder, walker_result)| {
builder
.build()
.map(|builder_result| (builder_result, walker_result))
- .into()
})
- .into()
+ .into_erased()
// B::from_seed(seed).map_with(walker, |builder, walker| walker.walk(builder.as_visitor()));
// E::wrap(async {
diff --git a/src/walk.rs b/src/walk.rs
index a8051fb..441410f 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -1,7 +1,7 @@
pub mod walkers;
use crate::{
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
protocol::DynVisitor,
Flow,
};
@@ -40,18 +40,21 @@ pub trait Walker<'ctx, E: Effect>: WalkerTypes + Send + Sync {
fn walk<'visitor: 'effect, 'effect>(
self,
visitor: DynVisitor<'visitor, 'ctx>,
- ) -> ObjSafe<'effect, Result<Self::Output, Self::Error>, E>
+ ) -> ErasedEffective<'effect, Result<Self::Output, Self::Error>, E>
where
Self: 'effect;
}
pub trait WalkerObjSafe<'ctx, E: Effect>: Send {
- fn walk<'a, 'b: 'a>(&'a mut self, visitor: DynVisitor<'b, 'ctx>) -> ObjSafe<'b, Flow, E>
+ fn walk<'a, 'b: 'a>(
+ &'a mut self,
+ visitor: DynVisitor<'b, 'ctx>,
+ ) -> ErasedEffective<'b, Flow, E>
where
Self: 'a;
}
-pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + Send + 'a);
+pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + Send + Sync + 'a);
enum DynWalkerState<W: WalkerTypes> {
Walking,
@@ -107,7 +110,7 @@ impl<W: WalkerTypes> DynWalkerAdapter<W> {
impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<W> {
#[inline(always)]
- fn walk<'a, 'b: 'a>(&'a mut self, visitor: DynVisitor<'b, 'ctx>) -> ObjSafe<'b, Flow, E>
+ fn walk<'a, 'b: 'a>(&'a mut self, visitor: DynVisitor<'b, 'ctx>) -> ErasedEffective<'b, Flow, E>
where
Self: 'a,
{
diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs
index 9045bf9..731bb79 100644
--- a/src/walk/walkers/core/key_value.rs
+++ b/src/walk/walkers/core/key_value.rs
@@ -1,7 +1,7 @@
use core::marker::PhantomData;
use crate::{
- effect::{Adapters, Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
never::Never,
protocol::{
visitor::{visit_tag, TagConst, TagError, TagKind, VisitResult},
@@ -60,22 +60,19 @@ where
fn walk<'b: 'c, 'c>(
self,
mut visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> {
E::ready(visitor)
- .as_ctx_for(move |visitor, _| {
- (
- self.value_walker
- .walk(visitor.cast())
- .map(|result| match result {
- Ok(_) => Ok::<_, Self::Error>(()),
- Err(_err) => todo!(),
- })
- .into(),
- PhantomData,
- )
+ .as_ctx(move |visitor| {
+ self.value_walker
+ .walk(visitor.cast())
+ .map(|result| match result {
+ Ok(_) => Ok::<_, Self::Error>(()),
+ Err(_err) => todo!(),
+ })
+ .into_erased()
})
.map(|(_, value)| value)
- .into()
+ .into_erased()
// E::wrap(async move {
// match visit_tag::<T, E, _>(self.tag, visitor.cast(), NoopWalker::new()).await {
diff --git a/src/walk/walkers/core/noop.rs b/src/walk/walkers/core/noop.rs
index 21d0880..6c846e7 100644
--- a/src/walk/walkers/core/noop.rs
+++ b/src/walk/walkers/core/noop.rs
@@ -1,5 +1,5 @@
use crate::{
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
never::Never,
protocol::DynVisitor,
WalkerTypes,
@@ -28,7 +28,7 @@ impl<'ctx, E: Effect> crate::Walker<'ctx, E> for NoopWalker {
fn walk<'b: 'c, 'c>(
self,
_visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
- E::ready(Ok(())).into()
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> {
+ E::ready(Ok(())).into_erased()
}
}
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs
index d6c8c4b..9dd5d68 100644
--- a/src/walk/walkers/core/struct.rs
+++ b/src/walk/walkers/core/struct.rs
@@ -3,7 +3,7 @@ use core::{any::TypeId, marker::PhantomData};
use crate::{
any::{AnyTrait, BorrowedStatic, BorrowedStaticHrt},
any_trait,
- effect::{Adapters, Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
hkt::Marker,
never::Never,
protocol::{
@@ -65,7 +65,7 @@ pub trait StructTypeInfo<'ctx, M>: 'static {
index: usize,
value: &'ctx Self::T,
visitor: DynVisitor<'a, 'ctx>,
- ) -> ObjSafe<'a, Result<Flow, Self::FieldError>, E>;
+ ) -> ErasedEffective<'a, Result<Flow, Self::FieldError>, E>;
}
#[derive(Debug, PartialEq, Clone, Copy)]
@@ -125,25 +125,22 @@ where
fn walk<'b: 'c, 'c>(
mut self,
mut visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E>
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E>
where
Self: 'c,
{
E::ready((self, visitor))
- .as_ctx_for(
+ .as_ctx(
#[inline(always)]
- |(this, visitor), _| {
- (
- RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()),
- PhantomData,
- )
+ |(this, visitor)| {
+ RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()).into_erased()
},
)
.map(|((this, _), _)| match this.error {
Some(err) => Err(StructWalkError { kind: err }),
None => Ok(()),
})
- .into()
+ .into_erased()
// E::ready(self).as_ctx_for::<'ctx, '_>(|this, _| {
// (RecoverableScope::<'ctx, E>::new_walk::<'_, 'b, '_>(this, visitor), PhantomData)
@@ -190,7 +187,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <RecoverableProto<E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_recoverable::<E>(visitor, self),
@@ -205,8 +202,8 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <RecoverableProto<E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> {
- E::ready(Ok(RecoverableKnown)).into()
+ ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> {
+ E::ready(Ok(RecoverableKnown)).into_erased()
}
}
@@ -221,7 +218,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: MetaHint<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>(
@@ -244,7 +241,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a MetaHint<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>,
- ) -> ObjSafe<
+ ) -> ErasedEffective<
'a,
Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>,
E,
@@ -252,7 +249,7 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into()
+ .into_erased()
}
}
@@ -267,7 +264,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>(
@@ -290,7 +287,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<
+ ) -> ErasedEffective<
'a,
Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, ()>,
E,
@@ -298,7 +295,7 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into()
+ .into_erased()
}
}
@@ -313,7 +310,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <TagProto<TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()),
@@ -332,12 +329,15 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <TagProto<TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, ()>, E>
- {
+ ) -> ErasedEffective<
+ 'a,
+ Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, ()>,
+ E,
+ > {
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into()
+ .into_erased()
}
}
@@ -352,7 +352,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>(
@@ -375,7 +375,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<
+ ) -> ErasedEffective<
'a,
Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, ()>,
E,
@@ -383,7 +383,7 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into()
+ .into_erased()
}
}
@@ -399,7 +399,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>(
@@ -422,7 +422,7 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta>::Hint,
- ) -> ObjSafe<
+ ) -> ErasedEffective<
'a,
Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, ()>,
E,
@@ -430,7 +430,7 @@ where
E::ready(Ok(TagKnown {
kind_available: Some(true),
}))
- .into()
+ .into_erased()
}
}
@@ -445,7 +445,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
hint: <TagProto<TagDyn, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
match hint.kind.0 {
crate::TAG_TYPE_ID => {
Hint::<'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>::hint(
@@ -477,7 +477,7 @@ where
'ctx,
TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>,
>::hint(self, visitor, TagHint { kind: TagConst }),
- _ => E::ready(Flow::Continue).into(),
+ _ => E::ready(Flow::Continue).into_erased(),
}
}
@@ -485,7 +485,7 @@ where
fn known<'a>(
&'a mut self,
hint: &'a <TagProto<TagDyn, E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagDyn, E>>, ()>, E> {
+ ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagDyn, E>>, ()>, E> {
E::ready(match hint.kind {
TagDyn(crate::TAG_TYPE_ID) | TagDyn(crate::TAG_STRUCT) => Ok(TagKnown {
kind_available: Some(true),
@@ -494,7 +494,7 @@ where
kind_available: Some(false),
}),
})
- .into()
+ .into_erased()
}
}
@@ -506,7 +506,11 @@ where
I::T: 'static,
{
#[inline(always)]
- fn hint<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>, _hint: ()) -> ObjSafe<'a, Flow, E> {
+ fn hint<'a>(
+ &'a mut self,
+ visitor: DynVisitor<'a, 'ctx>,
+ _hint: (),
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(
// visit_value::<_, E>(visitor, BorrowedStatic(self.value)),
@@ -521,8 +525,8 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a (),
- ) -> ObjSafe<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> {
- E::ready(Ok(ValueKnown { preview: None })).into()
+ ) -> ErasedEffective<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> {
+ E::ready(Ok(ValueKnown { preview: None })).into_erased()
}
}
@@ -536,7 +540,7 @@ where
&'a mut self,
visitor: DynVisitor<'a, 'ctx>,
_hint: <SequenceProto<E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Flow, E> {
+ ) -> ErasedEffective<'a, Flow, E> {
todo!()
// E::map(visit_sequence::<E>(visitor, self), |status| match status {
// VisitResult::Skipped(_) => Flow::Continue,
@@ -548,13 +552,13 @@ where
fn known<'a>(
&'a mut self,
_hint: &'a <SequenceProto<E> as HintMeta>::Hint,
- ) -> ObjSafe<'a, Result<MetaKnown<'a, 'ctx, SequenceProto<E>>, ()>, E> {
+ ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, SequenceProto<E>>, ()>, E> {
let len = I::FIELDS.len();
E::ready(Ok(SequenceKnown {
len: (len, Some(len)),
}))
- .into()
+ .into_erased()
}
}
@@ -564,16 +568,16 @@ where
I: StructTypeInfo<'ctx, M, S = S>,
{
#[inline(always)]
- fn size_hint(&mut self) -> ObjSafe<'_, (usize, Option<usize>), E> {
+ fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> {
let len = I::FIELDS.len();
- E::ready((len, Some(len))).into()
+ E::ready((len, Some(len))).into_erased()
}
#[inline(always)]
- fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ObjSafe<'a, Flow, E> {
+ fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ErasedEffective<'a, Flow, E> {
if self.index >= I::FIELDS.len() {
- return E::ready(Flow::Done).into();
+ return E::ready(Flow::Done).into_erased();
}
let index = self.index;
@@ -588,7 +592,7 @@ where
Flow::Err
}
})
- .into()
+ .into_erased()
// E::map(
// I::walk_field::<E>(index, self.value, visitor),
@@ -614,18 +618,17 @@ where
fn new_walk<'a: 'c, 'b: 'c, 'c>(
&'a mut self,
mut visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Status, E> {
+ ) -> ErasedEffective<'c, Status, E> {
// Reset the errors to default state.
self.error = None;
// Reset the field index to the default.
self.index = 0;
- E::with(
- (self, visitor),
- #[inline(always)]
- |(this, visitor), _| {
- (
+ E::ready((self, visitor))
+ .as_ctx(
+ #[inline(always)]
+ |(this, visitor)| {
visit_sequence::<E>(visitor.cast(), *this)
.map(|result| {
match result {
@@ -636,12 +639,11 @@ where
Ok(())
})
- .into(),
- PhantomData,
- )
- },
- )
- .into()
+ .into_erased()
+ },
+ )
+ .map(|(_, value)| value)
+ .into_erased()
// E::wrap(async move {
// // // We should check if the visitor wants something specific.
diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs
index d94887d..36d0013 100644
--- a/src/walk/walkers/core/tag.rs
+++ b/src/walk/walkers/core/tag.rs
@@ -3,7 +3,7 @@ use core::marker::PhantomData;
use crate::{
any::OwnedStatic,
any_trait,
- effect::{Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
never::Never,
protocol::{
visitor::{
@@ -47,7 +47,7 @@ where
fn walk<'b: 'c, 'c>(
mut self,
mut visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> {
todo!()
// E::wrap(async move {
// match visit_request_hint::<E>(visitor.cast(), DynWalker(&mut self)).await {
@@ -84,7 +84,7 @@ where
&'static T: Into<W>,
{
#[inline(always)]
- fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ObjSafe<'a, Flow, E> {
+ fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ErasedEffective<'a, Flow, E> {
if let Some(name) = self.names.get(self.current) {
self.current += 1;
todo!()
@@ -95,12 +95,12 @@ where
// }
// })
} else {
- E::ready(Flow::Done).into()
+ E::ready(Flow::Done).into_erased()
}
}
#[inline(always)]
- fn size_hint(&mut self) -> ObjSafe<'_, (usize, Option<usize>), E> {
- E::ready((self.names.len(), Some(self.names.len()))).into()
+ fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> {
+ E::ready((self.names.len(), Some(self.names.len()))).into_erased()
}
}
diff --git a/src/walk/walkers/core/value.rs b/src/walk/walkers/core/value.rs
index eec00b5..bc6a44f 100644
--- a/src/walk/walkers/core/value.rs
+++ b/src/walk/walkers/core/value.rs
@@ -1,6 +1,6 @@
use crate::{
any::{BorrowedStatic, OwnedStatic},
- effect::{Adapters, Effect, ObjSafe},
+ effect::{Effect, Effective, ErasedEffective},
never::Never,
protocol::{visitor::visit_value, DynVisitor},
WalkerTypes,
@@ -46,11 +46,11 @@ impl<'ctx, T: Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> for Value
fn walk<'b: 'c, 'c>(
self,
visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> {
// Attempt to visit using the value protocol.
visit_value::<_, E>(visitor, OwnedStatic(self.0))
.map(|_| Ok(()))
- .into()
+ .into_erased()
// E::map(
// visit_value::<_, E>(visitor, OwnedStatic(self.0)),
// |_| Ok(()),
@@ -84,7 +84,7 @@ impl<'ctx, T: ?Sized + Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E>
fn walk<'b: 'c, 'c>(
self,
visitor: DynVisitor<'b, 'ctx>,
- ) -> ObjSafe<'c, Result<Self::Output, Self::Error>, E> {
+ ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> {
// Attempt to visit using the value protocol.
todo!()
// E::map(visit_value::<_, E>(visitor, BorrowedStatic(self.0)), |_| {
diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs
index 8aca415..c0cb843 100644
--- a/tests/builder_struct.rs
+++ b/tests/builder_struct.rs
@@ -1,7 +1,7 @@
use treaty::{
any::{OwnedStatic, TempBorrowedStatic},
builders::{self, core::r#struct::StructBuilder},
- effect::{Blocking, Effect, ObjSafe},
+ effect::{ErasedEffective, Effect, Effective},
protocol::{
visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult},
DynVisitor,
@@ -45,7 +45,7 @@ impl<'ctx, M> walkers::core::r#struct::StructTypeInfo<'ctx, M> for Info {
index: usize,
value: &'ctx Self::T,
visitor: DynVisitor<'a, 'ctx>,
- ) -> ObjSafe<'a, Result<Flow, Self::FieldError>, E> {
+ ) -> ErasedEffective<'a, Result<Flow, Self::FieldError>, E> {
todo!()
// E::wrap(async move {
// match index {
@@ -108,7 +108,7 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo
type Error = ();
#[inline(always)]
- fn from_builders<'a>(builders: Self::Builders) -> ObjSafe<'a, Result<Self::T, Self::Error>, E> {
+ fn from_builders<'a>(builders: Self::Builders) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> {
todo!()
// E::wrap(async {
// Ok(X {
@@ -132,7 +132,7 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo
type Seed = ();
#[inline(always)]
- fn new_builders<'a>(_seed: Self::Seed) -> ObjSafe<'a, Self::Builders, E> {
+ fn new_builders<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E> {
todo!()
// E::wrap(async {
// Fields {
@@ -293,7 +293,7 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo
pub mod demo {
use crate::Walk;
use macro_rules_attribute::derive;
- use treaty::{effect::Blocking, transform, Build, DefaultMode};
+ use treaty::{effect::{r#async::Async, blocking::{BlockOn, Blocking, Spin}, Effective as _}, transform, Build, DefaultMode};
#[derive(Walk!, Debug)]
pub struct X {
@@ -309,11 +309,12 @@ pub mod demo {
#[no_mangle]
pub fn ident(x: X) -> Y {
- let other = transform::<<Y as crate::Build<'_, DefaultMode, _>>::Builder, _, Blocking>(
+ let other = transform::<<Y as crate::Build<'_, DefaultMode, _>>::Builder, _, Blocking<Spin>>(
((), ()),
Walk::<DefaultMode, _>::into_walker(&x),
- )
- .0;
+ );
+
+ let other = Spin::block_on(other.into_future());
other.0.unwrap()
}