28 files changed, 1171 insertions, 726 deletions
@@ -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()), }; @@ -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; @@ -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() } |