tests compile
29 files changed, 647 insertions, 580 deletions
diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 7e8d854..d1889b3 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -202,49 +202,30 @@ where .map(|(_, value)| value) .into_erased() } - StructMode::Map => { - todo!() - } + StructMode::Map => E::ready((self, scope)) + .r#loop(|(this, scope)| { + let visitor = FieldVisitor::<I, M, E> { + builders: &mut this.builders, + marker: None, + _marker: Default::default(), + }; + + E::ready((scope, visitor)) + .as_ctx(|(scope, visitor)| { + let scope: &mut DynSequenceScope<'_, '_, _> = scope; + + scope.next(DynVisitor(visitor)).into_erased() + }) + .map(|(_, result)| match result { + Flow::Continue => ControlFlow::Continue(()), + Flow::Err => ControlFlow::Break(VisitResult::Control(Flow::Err)), + Flow::Done => ControlFlow::Break(VisitResult::Control(Flow::Done)), + }) + .into_erased() + }) + .map(|(_, value)| value) + .into_erased(), } - - // match self.mode { - // StructMode::Tuple => E::wrap(async { - // let mut index = 0; - // - // // For each index based marker. - // while let Some(marker) = I::marker_from_index(index) { - // // Select the visitor for this field. - // let visitor = I::as_visitor(marker, &mut self.builders); - // - // // Get the next value in the sequence. - // match scope.next(visitor).await { - // Flow::Continue => {} - // Flow::Err => return VisitResult::Control(Flow::Err), - // Flow::Done => break, - // } - // - // // Move to the next field. - // index += 1; - // } - // - // VisitResult::Control(Flow::Done) - // }), - // StructMode::Map => E::wrap(async { - // loop { - // let mut visitor = FieldVisitor::<I, M, E> { - // builders: &mut self.builders, - // marker: None, - // _marker: Default::default(), - // }; - // - // match scope.next(DynVisitor(&mut visitor)).await { - // Flow::Continue => {} - // Flow::Err => return VisitResult::Control(Flow::Err), - // Flow::Done => return VisitResult::Control(Flow::Done), - // } - // } - // }), - // } } } @@ -282,20 +263,18 @@ where _key: tags::Key, walker: DynWalkerObjSafe<'b, 'ctx, E>, ) -> ErasedEffective<'c, VisitResult<DynWalkerObjSafe<'b, 'ctx, E>>, E> { - todo!() - // E::wrap(async { - // let mut visitor = NameVisitor::<I, M, E> { - // field_marker: None, - // _marker: Default::default(), - // }; - // - // let flow = walker.walk(DynVisitor(&mut visitor)).await; - // - // self.marker = visitor.field_marker; - // - // // We are expecting the value of the field to be given next. - // flow.to_continue().into() - // }) + let visitor = NameVisitor::<I, M, E> { + field_marker: None, + _marker: Default::default(), + }; + + E::ready((self, visitor, walker)) + .as_ctx(|(_, visitor, walker)| walker.walk(DynVisitor(visitor)).into_erased()) + .map(|((this, visitor, _), flow)| { + this.marker = visitor.field_marker; + flow.to_continue().into() + }) + .into_erased() } } diff --git a/src/effect.rs b/src/effect.rs index 0c85769..87cee7e 100644 --- a/src/effect.rs +++ b/src/effect.rs @@ -38,81 +38,99 @@ use crate::{higher_ranked_trait, higher_ranked_type}; // || B // )) -pub trait Effect: - Join<Effect = Self> + TryJoin<Effect = Self> + Send + Sync + Sized + 'static -{ - type Erased<T: Send + Sync>: ErasedHrt<T, Self>; +pub trait Ss: Send + Sync {} + +impl<T: Send + Sync> Ss for T {} + +pub trait Effect: Join<Effect = Self> + TryJoin<Effect = Self> + Ss + Sized + 'static { + type Erased<T: Ss>: ErasedHrt<T, Self>; - type Ready<'a, T: Send + Sync + 'a>: Effective<'a, Output = T, Effect = Self>; + type Ready<'a, T: Ss + 'a>: Effective<'a, Output = T, Effect = Self>; - fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T>; + fn ready<'a, T: Ss + 'a>(value: T) -> Self::Ready<'a, T>; - type FromFuture<'a, F: Send + Sync + 'a>: Effective<'a, Output = F::Output, Effect = Self> + type FromFuture<'a, F: Ss + 'a>: Effective<'a, Output = F::Output, Effect = Self> where F: Future, - F::Output: Send + Sync + 'a; + F::Output: Ss + 'a; - fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> + fn from_future<'a, F: Ss + 'a>(future: F) -> Self::FromFuture<'a, F> where F: Future, - F::Output: Send + Sync + 'a; + F::Output: Ss + 'a; } -pub trait ErasedForLt<'a, T: Send + Sync + 'a, E: Effect, Bound: 'a, O: 'a> { +pub trait ErasedForLt<'a, T: Ss + 'a, E: Effect, Bound: 'a, O: 'a> { type T: Effective<'a, Output = T, Effect = E>; } -pub trait ErasedHrt<T: Send + Sync, E: Effect> { +pub trait ErasedHrt<T: Ss, E: Effect> { type T<B>: for<'a> ErasedForLt<'a, T, E, &'a (T, B), B>; } 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 { + <<<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>: Ss + 'lt { fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B>; /// The effect the effective belongs to. type Effect: Effect; /// The type of the effective's output value. - type Output: Send + Sync + 'lt; + type Output: Ss + 'lt; /// Future that resolves to the same value as the effective. - type IntoFuture: Send + Sync + Future<Output = Self::Output>; + type IntoFuture: Ss + Future<Output = Self::Output>; /// Convert the effective into a general future for use in async. fn into_future(self) -> Self::IntoFuture; - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + '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 ())>, + 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> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + '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 ())>, + 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, - Output = T, - Effect = Self::Effect, - > + type Map<'a, T: Ss + 'a, F: Ss + 'a>: Effective<'a, Output = T, Effect = Self::Effect> 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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'lt: 'a; - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>: Effective< 'a, Output = T, Effect = Self::Effect, @@ -122,40 +140,43 @@ pub trait Effective<'lt>: Send + Sync + 'lt { 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> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'lt: 'a; - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>: Effective< + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>: Effective< 'a, Output = (Self::Output, T), Effect = Self::Effect, > where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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; + type Ok: Ss + 'lt; + type Err: Ss + '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, + Ok: Ss + 'lt, + Err: Ss + 'lt, { type Ok = Ok; @@ -165,7 +186,7 @@ where pub trait Join { type Effect: Effect; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>: Effective< + type Two<'a, T0: Ss + 'a, T1: Ss + 'a>: Effective< 'a, Output = (T0::Output, T1::Output), Effect = Self::Effect, @@ -174,7 +195,7 @@ pub trait Join { T0: Effective<'a, Effect = Self::Effect>, T1: Effective<'a, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>: Effective< + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>: Effective< 'a, Output = (T0::Output, T1::Output, T2::Output), Effect = Self::Effect, @@ -184,14 +205,12 @@ 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>( - effectives: (T0, T1), - ) -> Self::Two<'a, T0, T1> + fn two<'a, T0: Ss + 'a, T1: Ss + 'a>(effectives: (T0, T1)) -> Self::Two<'a, T0, T1> where T0: Effective<'a, Effect = Self::Effect>, T1: Effective<'a, Effect = Self::Effect>; - fn three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>( effectives: (T0, T1, T2), ) -> Self::Three<'a, T0, T1, T2> where @@ -203,7 +222,7 @@ pub trait Join { pub trait TryJoin { type Effect: Effect; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>: Effective< + type Two<'a, T0: Ss + 'a, T1: Ss + 'a>: Effective< 'a, Output = Result<(T0::Ok, T1::Ok), T0::Err>, Effect = Self::Effect, @@ -212,7 +231,7 @@ pub trait TryJoin { T0: TryEffective<'a, Effect = Self::Effect>, T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>: Effective< + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>: Effective< 'a, Output = Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, Effect = Self::Effect, @@ -222,13 +241,7 @@ pub trait TryJoin { T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, T2: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - fn two< - 'a, - T0: Send + Sync + 'a, - T1: Send + Sync + 'a, - F0: Send + Sync + 'a, - F1: Send + Sync + 'a, - >( + fn two<'a, T0: Ss + 'a, T1: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a>( cb: (F0, F1), ) -> Self::Two<'a, T0, T1> where @@ -237,15 +250,7 @@ pub trait TryJoin { F0: FnOnce() -> T0, F1: FnOnce() -> T1; - 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, - >( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a, F2: Ss + 'a>( cb: (F0, F1, F2), ) -> Self::Three<'a, T0, T1, T2> where @@ -343,8 +348,8 @@ where 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, + F0: FnOnce() -> T0 + Ss + 'lt, + F1: FnOnce() -> T1 + Ss + 'lt, T0: TryEffective<'lt, Effect = E>, T1: TryEffective<'lt, Err = T0::Err, Effect = E>, { diff --git a/src/effect/async.rs b/src/effect/async.rs index ffe8bb7..effcd08 100644 --- a/src/effect/async.rs +++ b/src/effect/async.rs @@ -21,7 +21,7 @@ use pin_project::pin_project; use crate::hkt::Marker; -use super::{Effect, Effective, ErasedEffective, ErasedForLt, Join, TryJoin}; +use super::{Effect, Effective, ErasedEffective, ErasedForLt, Join, Ss, TryJoin}; pub enum Async {} @@ -40,38 +40,38 @@ pub enum BoxOrReady<'a, T> { pub type BoxedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + Sync + 'a>>; -impl<'a, T: Send + Sync, O> ErasedForLt<'a, T, Async, &'a (T, O), O> for ErasedHrt<T> { +impl<'a, T: Ss, O> ErasedForLt<'a, T, Async, &'a (T, O), O> for ErasedHrt<T> { type T = BoxOrReady<'a, T>; } -impl<T: Send + Sync> super::ErasedHrt<T, Async> for ErasedHrt<T> { +impl<T: Ss> super::ErasedHrt<T, Async> for ErasedHrt<T> { type T<B> = ErasedHrt<T>; } impl Effect for Async { - type Erased<T: Send + Sync> = ErasedHrt<T>; + type Erased<T: Ss> = ErasedHrt<T>; - type Ready<'a, T: Send + Sync + 'a> = Value<T>; + type Ready<'a, T: Ss + 'a> = Value<T>; - fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> { + fn ready<'a, T: Ss + 'a>(value: T) -> Self::Ready<'a, T> { Value(value) } - type FromFuture<'a, F: Send + Sync + 'a> = Shim<F> + type FromFuture<'a, F: Ss + 'a> = Shim<F> where F: futures::prelude::Future, - F::Output: Send + Sync + 'a; + F::Output: Ss + 'a; - fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> + fn from_future<'a, F: Ss + 'a>(future: F) -> Self::FromFuture<'a, F> where F: futures::prelude::Future, - F::Output: Send + Sync + 'a, + F::Output: Ss + 'a, { Shim::new(future) } } -impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { +impl<'lt, U: Ss + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { fn into_erased<B>(self) -> super::ErasedEffective<'lt, Self::Output, Self::Effect, B> { self } @@ -89,13 +89,13 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { } } - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (U, T)> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'lt: 'a; - fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'lt: 'a, @@ -111,12 +111,12 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { })) } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Map<ErasedFuture<'lt, U>, F> + type Map<'a, T: Ss + 'a, F: Ss + 'a> = Map<ErasedFuture<'lt, 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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'lt: 'a, @@ -124,17 +124,14 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { Map::new(self.into_future(), cb) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = Then<'a, ErasedFuture<'lt, U>, F, V> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'lt: 'a; - fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( - self, - cb: F, - ) -> Self::Then<'a, T, V, F> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -143,13 +140,13 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { Then::new(self.into_future(), cb) } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (Self::Output, T)> where F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, 'lt: 'a; - fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where F: for<'b> FnOnce(&'b mut Self::Output) -> super::ErasedEffective<'b, T, Self::Effect>, 'lt: 'a, @@ -167,20 +164,20 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for BoxOrReady<'lt, U> { impl Join for Async { type Effect = Self; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> + type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Shim<futures::future::Join<T0::IntoFuture, T1::IntoFuture>> where T0: super::Effective<'a, Effect = Self::Effect>, T1: super::Effective<'a, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Shim<futures::future::Join3<T0::IntoFuture, T1::IntoFuture, T2::IntoFuture, >> where T0: super::Effective<'a, Effect = Self::Effect>, T1: super::Effective<'a, Effect = Self::Effect>, T2: super::Effective<'a, Effect = Self::Effect>; - fn two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0: Ss + 'a, T1: Ss + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> where T0: super::Effective<'a, Effect = Self::Effect>, T1: super::Effective<'a, Effect = Self::Effect>, @@ -191,7 +188,7 @@ impl Join for Async { )) } - fn three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>( cb: (T0, T1, T2), ) -> Self::Three<'a, T0, T1, T2> where @@ -210,26 +207,20 @@ impl Join for Async { impl TryJoin for Async { type Effect = Self; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> + type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Shim<futures::future::TryJoin<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>>> where T0: super::TryEffective<'a, Effect = Self::Effect>, T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Shim<futures::future::TryJoin3<BoxedFuture<'a, T0::Output>, BoxedFuture<'a, T1::Output>, BoxedFuture<'a, T2::Output>>> where T0: super::TryEffective<'a, Effect = Self::Effect>, T1: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, T2: super::TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - fn two< - 'a, - T0: Send + Sync + 'a, - T1: Send + Sync + 'a, - F0: Send + Sync + 'a, - F1: Send + Sync + 'a, - >( + fn two<'a, T0: Ss + 'a, T1: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a>( cb: (F0, F1), ) -> Self::Two<'a, T0, T1> where @@ -244,15 +235,7 @@ impl TryJoin for Async { )) } - 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, - >( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a, F2: Ss + 'a>( cb: (F0, F1, F2), ) -> Self::Three<'a, T0, T1, T2> where diff --git a/src/effect/async/map.rs b/src/effect/async/map.rs index d8c1331..45bee06 100644 --- a/src/effect/async/map.rs +++ b/src/effect/async/map.rs @@ -7,7 +7,7 @@ use core::{ use futures::Future; use pin_project::pin_project; -use crate::effect::{Effective, ErasedEffective}; +use crate::effect::{Effective, ErasedEffective, Ss}; use super::{Async, BoxOrReady, Then}; @@ -64,8 +64,7 @@ where } } -impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, F0: Send + Sync + 'c, R0: Send + Sync + 'c> Effective<'c> - for Map<Fut0, F0> +impl<'c, 'lt: 'c, Fut0: Ss + 'lt, F0: Ss + 'c, R0: Ss + 'c> Effective<'c> for Map<Fut0, F0> where F0: FnOnce(Fut0::Output) -> R0, Fut0: Future, @@ -85,15 +84,22 @@ where self } - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (R0, T)> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, 'c: 'a; - fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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 { @@ -107,13 +113,13 @@ where })) } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = + type Map<'a, T: Ss + 'a, F: Ss + '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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'c: 'a, @@ -121,17 +127,14 @@ where Map::new(self, cb) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = Then<'a, Self, F, V> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'c: 'a; - fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( - self, - cb: F, - ) -> Self::Then<'a, T, V, F> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -140,13 +143,13 @@ where Then::new(self, cb) } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (Self::Output, T)> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'c: 'a; - fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'c: 'a, diff --git a/src/effect/async/shim.rs b/src/effect/async/shim.rs index fcc16ae..484f49b 100644 --- a/src/effect/async/shim.rs +++ b/src/effect/async/shim.rs @@ -2,7 +2,7 @@ use core::ops::ControlFlow; use futures::Future; -use crate::effect::{Effective, ErasedEffective}; +use crate::effect::{Effective, ErasedEffective, Ss}; use super::{Async, BoxOrReady, Map, Then}; @@ -16,10 +16,10 @@ impl<F> Shim<F> { } } -impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Shim<U> +impl<'lt, U: Ss + 'lt> Effective<'lt> for Shim<U> where U: Future, - U::Output: Send + Sync + 'lt, + U::Output: Ss + 'lt, { fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B> { BoxOrReady::Boxed(Box::pin(self.future)) @@ -35,15 +35,22 @@ where self.future } - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (U::Output, T)> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, 'lt: 'a; - fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where - F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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 { @@ -57,13 +64,13 @@ where })) } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Map<'a, T: Ss + 'a, F: Ss + '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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'lt: 'a, @@ -71,17 +78,14 @@ where Map::new(self.future, cb) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = Then<'a, U, F, V> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'lt: 'a; - fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( - self, - cb: F, - ) -> Self::Then<'a, T, V, F> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -90,13 +94,13 @@ where Then::new(self.future, cb) } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (Self::Output, T)> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'lt: 'a; - fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'lt: 'a, diff --git a/src/effect/async/then.rs b/src/effect/async/then.rs index 96b2c8c..2ffc705 100644 --- a/src/effect/async/then.rs +++ b/src/effect/async/then.rs @@ -7,7 +7,7 @@ use core::{ use futures::Future; use pin_project::pin_project; -use crate::effect::{Effective, ErasedEffective}; +use crate::effect::{Effective, ErasedEffective, Ss}; use super::{map::Map, Async, BoxOrReady}; @@ -88,13 +88,13 @@ where } } -impl<'c, 'lt: 'c, Fut0: Send + Sync + 'lt, V0: Send + Sync + 'lt, F0: Send + Sync + 'c> - Effective<'c> for Then<'lt, Fut0, F0, V0> +impl<'c, 'lt: 'c, Fut0: Ss + 'lt, V0: Ss + 'lt, F0: Ss + 'c> Effective<'c> + for Then<'lt, Fut0, F0, V0> where F0: FnOnce(Fut0::Output) -> V0, V0: Effective<'lt>, Fut0: Future, - Fut0::Output: Send + Sync + 'lt, + Fut0::Output: Ss + 'lt, { fn into_erased<B>(self) -> ErasedEffective<'c, Self::Output, Self::Effect, B> { BoxOrReady::Boxed(Box::pin(self)) @@ -110,13 +110,13 @@ where self } - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (V0::Output, T)> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'c: 'a; - fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'c: 'a, @@ -132,13 +132,13 @@ where })) } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Map<'a, T: Ss + 'a, F: Ss + '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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'c: 'a, @@ -146,17 +146,14 @@ where Map::new(self, cb) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = Then<'a, Self, F, V> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'c: 'a; - fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( - self, - cb: F, - ) -> Self::Then<'a, T, V, F> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -165,13 +162,13 @@ where Then::new(self, cb) } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (Self::Output, T)> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'c: 'a; - fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, 'c: 'a, diff --git a/src/effect/async/value.rs b/src/effect/async/value.rs index c3a80ca..63b2e25 100644 --- a/src/effect/async/value.rs +++ b/src/effect/async/value.rs @@ -1,12 +1,12 @@ use core::ops::ControlFlow; -use crate::effect::{Effective, ErasedEffective}; +use crate::effect::{Effective, ErasedEffective, Ss}; use super::{Async, BoxOrReady}; pub struct Value<T>(pub T); -impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { +impl<'lt, U: Ss + 'lt> Effective<'lt> for Value<U> { fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B> { BoxOrReady::Ready(self.0) } @@ -21,13 +21,13 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { core::future::ready(self.0) } - type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (U, T)> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'lt: 'a; - fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'lt: 'a, @@ -43,13 +43,13 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { })) } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type Map<'a, T: Ss + 'a, F: Ss + '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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'lt: 'a, @@ -57,17 +57,14 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { Value(cb(self.0)) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = V where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, 'lt: 'a; - fn then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>( - self, - cb: F, - ) -> Self::Then<'a, T, V, F> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -76,15 +73,18 @@ impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Value<U> { cb(self.0) } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = BoxOrReady<'a, (Self::Output, T)> where F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, 'lt: 'a; - fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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 { diff --git a/src/effect/blocking.rs b/src/effect/blocking.rs index 661fd12..5913dda 100644 --- a/src/effect/blocking.rs +++ b/src/effect/blocking.rs @@ -13,43 +13,49 @@ pub trait BlockOn: 'static { <F as core::future::Future>::Output: Send; } -pub struct Blocking<B>(Marker<B>); +pub struct Blocking<B = Spin>(Marker<B>); #[repr(transparent)] pub struct Value<T, B>(pub T, Marker<B>); -impl<'lt, T: Send + Sync, B: BlockOn, O> ErasedForLt<'lt, T, Blocking<B>, &'lt (T, O), O> for Value<T, B> { +impl<T, B> Value<T, B> { + pub fn value(self) -> T { + self.0 + } +} + +impl<'lt, T: Ss, 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> { +impl<T: Ss, 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>; + type Erased<T: Ss> = Value<T, B>; - type Ready<'a, T: Send + Sync + 'a> = Value<T, B>; + type Ready<'a, T: Ss + 'a> = Value<T, B>; - fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> { + fn ready<'a, T: Ss + 'a>(value: T) -> Self::Ready<'a, T> { Value(value, Default::default()) } - type FromFuture<'a, F: Send + Sync + 'a> = Value<F::Output, B> + type FromFuture<'a, F: Ss + 'a> = Value<F::Output, B> where F: Future, - F::Output: Send + Sync + 'a; + F::Output: Ss + 'a; - fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> + fn from_future<'a, F: Ss + 'a>(future: F) -> Self::FromFuture<'a, F> where F: Future, - F::Output: Send + Sync + 'a, + F::Output: Ss + 'a, { Value(B::block_on(future), Default::default()) } } -impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { +impl<'lt, U: Ss + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { fn into_erased<X>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, X> { self } @@ -64,13 +70,13 @@ 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> + type Loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + '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> + fn r#loop<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, mut cb: F) -> Self::Loop<'ctx, 'a, T, F> where F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>, 'lt: 'a, @@ -84,12 +90,12 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { } } - type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B> + type Map<'a, T: Ss + 'a, F: Ss + 'a> = Value<T, B> 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> + fn map<'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Map<'a, T, F> where F: FnOnce(Self::Output) -> T, 'lt: 'a, @@ -97,16 +103,13 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { Value(cb(self.0), Default::default()) } - type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B> + type Then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a> = Value<T, B> 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> + fn then<'a, T: Ss + 'a, V: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::Then<'a, T, V, F> where F: FnOnce(Self::Output) -> V, V: Effective<'a, Output = T, Effect = Self::Effect>, @@ -115,14 +118,17 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { cb(self.0).into_erased::<()>() } - type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<(U, T), B> + type AsCtx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a> = Value<(U, T), B> 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> + fn as_ctx<'ctx: 'a, 'a, T: Ss + 'a, F: Ss + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F> where - F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect, (&'b mut Self::Output, &'ctx ())>, + 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; @@ -134,18 +140,18 @@ impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { impl<B: BlockOn> Join for Blocking<B> { type Effect = Blocking<B>; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<(T0::Output, T1::Output), B> + type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Value<(T0::Output, T1::Output), B> where T0: Effective<'a, Effect = Self::Effect>, T1: Effective<'a, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<(T0::Output, T1::Output, T2::Output), B> + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Value<(T0::Output, T1::Output, T2::Output), B> where T0: Effective<'a, Effect = Self::Effect>, T1: Effective<'a, Effect = Self::Effect>, T2: Effective<'a, Effect = Self::Effect>; - fn two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> + fn two<'a, T0: Ss + 'a, T1: Ss + 'a>(cb: (T0, T1)) -> Self::Two<'a, T0, T1> where T0: Effective<'a, Effect = Self::Effect>, T1: Effective<'a, Effect = Self::Effect>, @@ -156,7 +162,7 @@ impl<B: BlockOn> Join for Blocking<B> { Value((v0, v1), Default::default()) } - fn three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a>( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>( cb: (T0, T1, T2), ) -> Self::Three<'a, T0, T1, T2> where @@ -175,24 +181,18 @@ impl<B: BlockOn> Join for Blocking<B> { impl<B: BlockOn> TryJoin for Blocking<B> { type Effect = Blocking<B>; - type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<Result<(T0::Ok, T1::Ok), T0::Err>, B> + type Two<'a, T0: Ss + 'a, T1: Ss + 'a> = Value<Result<(T0::Ok, T1::Ok), T0::Err>, B> where T0: TryEffective<'a, Effect = Self::Effect>, T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, B> + type Three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a> = Value<Result<(T0::Ok, T1::Ok, T2::Ok), T0::Err>, B> where T0: TryEffective<'a, Effect = Self::Effect>, T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, T2: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>; - fn two< - 'a, - T0: Send + Sync + 'a, - T1: Send + Sync + 'a, - F0: Send + Sync + 'a, - F1: Send + Sync + 'a, - >( + fn two<'a, T0: Ss + 'a, T1: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a>( cb: (F0, F1), ) -> Self::Two<'a, T0, T1> where @@ -214,15 +214,7 @@ impl<B: BlockOn> TryJoin for Blocking<B> { Value(Ok((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, - >( + fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a, F2: Ss + 'a>( cb: (F0, F1, F2), ) -> Self::Three<'a, T0, T1, T2> where diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs index 61ac4b7..2c13785 100644 --- a/src/protocol/visitor/tag.rs +++ b/src/protocol/visitor/tag.rs @@ -8,7 +8,7 @@ use crate::{ DynVisitor, }, symbol::Symbol, - DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe, WalkerTypes, + DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe, Flow, WalkerTypes, }; use super::VisitResult; @@ -174,49 +174,62 @@ where W: WalkerTypes, { // Wrap the walker to allow it to be passed to a dyn walker argument. - let mut walker = DynWalkerAdapter::new(walker); - todo!() - - // E::wrap(async move { - // let result = if let Some(object) = visitor.upcast_mut::<TagProto<K, E>>() { - // // The visitor knows about this tag. - // - // // Visit the tag. - // object.visit(kind, &mut walker).await - // } else if core::any::TypeId::of::<TagDyn>() != core::any::TypeId::of::<K>() { - // // Try the dynamic form if we didn't already. - // if let Some(object) = visitor.upcast_mut::<TagProto<TagDyn, E>>() { - // // The visitor can handle dynamic tags. - // // If the visitor can't handle the tag kind then it can call .skip on the walker - // // to disable the error for not walking it. - // - // // Visit the tag. - // object.visit(TagDyn(kind.symbol()), &mut walker).await - // } else { - // let walker: W = walker - // .into_innter() - // .map_err(|err| map_walker_err(kind, err))?; - // return Ok(VisitResult::Skipped(walker)); - // } - // } else { - // let walker: W = walker - // .into_innter() - // .map_err(|err| map_walker_err(kind, err))?; - // return Ok(VisitResult::Skipped(walker)); - // }; - // - // match result { - // // The walker was skipped. - // VisitResult::Skipped(_) => match walker.into_innter() { - // Ok(walker) => Ok(VisitResult::Skipped(walker)), - // Err(err) => Err(map_walker_err(kind, err)), - // }, - // VisitResult::Control(flow) => match walker.finish() { - // Ok(_) => Ok(VisitResult::Control(flow)), - // Err(err) => Err(map_walker_err(kind, err)), - // }, - // } - // }) + let walker = DynWalkerAdapter::new(walker); + + E::ready((kind, visitor, walker)) + .as_ctx(|(kind, visitor, walker)| { + let object = visitor.upcast_mut::<TagProto<K, E>>(); + + E::ready((*kind, object, walker)) + .as_ctx(|(kind, object, walker)| match object { + Some(object) => object + .visit(*kind, &mut **walker) + .map(|value| match value { + VisitResult::Skipped(_) => None, + VisitResult::Control(flow) => Some(flow), + }) + .into_erased(), + None => E::ready(None).into_erased(), + }) + .map(|((_, _, _), value)| value) + .into_erased() + }) + .as_ctx(|((kind, visitor, walker), result)| { + if result.is_some() || core::any::TypeId::of::<TagDyn>() != core::any::TypeId::of::<K>() + { + E::ready(None).into_erased() + } else { + let object = visitor.upcast_mut::<TagProto<TagDyn, E>>(); + + E::ready((*kind, object, walker)) + .as_ctx(|(kind, object, walker)| match object { + Some(object) => object + .visit(TagDyn(kind.symbol()), &mut **walker) + .map(|value| match value { + VisitResult::Skipped(_) => None, + VisitResult::Control(flow) => Some(flow), + }) + .into_erased(), + None => E::ready(None).into_erased(), + }) + .map(|((_, _, _), value)| value) + .into_erased() + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .map(|((kind, _, walker), result)| match result { + Some(flow) => Ok(VisitResult::Control(flow)), + None => match walker.into_inner() { + Ok(walker) => Ok(VisitResult::Skipped(walker)), + Err(err) => Err(map_walker_err(kind, err)), + }, + }) + .into_erased() } #[inline(always)] diff --git a/src/transform.rs b/src/transform.rs index 4652b9b..bd358bf 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -14,10 +14,7 @@ pub fn transform<'a, 'ctx: 'a, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a walker: W, ) -> ErasedEffective<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> { B::from_seed(seed) - .as_ctx( - #[inline(always)] - move |builder| walker.walk(builder.as_visitor()).into_erased(), - ) + .as_ctx(|builder| walker.walk(builder.as_visitor()).into_erased()) .then(|(builder, walker_result)| { builder .build() diff --git a/src/walk.rs b/src/walk.rs index 441410f..159e9ea 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -46,10 +46,10 @@ pub trait Walker<'ctx, E: Effect>: WalkerTypes + Send + Sync { } pub trait WalkerObjSafe<'ctx, E: Effect>: Send { - fn walk<'a, 'b: 'a>( + fn walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'b, Flow, E> + ) -> ErasedEffective<'c, Flow, E> where Self: 'a; } @@ -98,7 +98,7 @@ impl<W: WalkerTypes> DynWalkerAdapter<W> { } #[inline(always)] - pub fn into_innter(self) -> Result<W, DynWalkerError<W>> { + pub fn into_inner(self) -> Result<W, DynWalkerError<W>> { match self.state { DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished), DynWalkerState::Pending(walker) => Ok(walker), @@ -110,33 +110,41 @@ 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>) -> ErasedEffective<'b, Flow, E> + fn walk<'a: 'c, 'b: 'c, 'c>( + &'a mut self, + visitor: DynVisitor<'b, 'ctx>, + ) -> ErasedEffective<'c, Flow, E> where Self: 'a, { - todo!() - // E::wrap(async { - // if let DynWalkerState::Pending(walker) = - // core::mem::replace(&mut self.state, DynWalkerState::Walking) - // { - // // Walk the walker. - // match walker.walk(visitor).await { - // Ok(value) => { - // self.state = DynWalkerState::Done(value); - // Flow::Done - // } - // Err(err) => { - // self.state = DynWalkerState::Err(err); - // - // // Signal that control flow should stop as soon as possible as we - // // are in an error state. - // Flow::Err - // } - // } - // } else { - // // Can't do anything if the walker has already been walked. - // Flow::Done - // } - // }) + if let DynWalkerState::Pending(walker) = + core::mem::replace(&mut self.state, DynWalkerState::Walking) + { + E::ready((self, visitor)) + .as_ctx(|(this, visitor)| { + // Walk the walker. + walker + .walk(visitor.cast()) + .map(|value| match value { + Ok(value) => { + this.state = DynWalkerState::Done(value); + Flow::Done + } + Err(err) => { + this.state = DynWalkerState::Err(err); + + // Signal that control flow should stop as soon as possible as we + // are in an error state. + Flow::Err + } + }) + .into_erased() + }) + .map(|(_, value)| value) + .into_erased() + } else { + // Can't do anything if the walker has already been walked. + E::ready(Flow::Done).into_erased() + } } } diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index 9dd5d68..88b597c 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -133,7 +133,8 @@ where .as_ctx( #[inline(always)] |(this, visitor)| { - RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()).into_erased() + RecoverableScope::<'ctx, E>::new_walk::<'_, '_, '_>(this, visitor.cast()) + .into_erased() }, ) .map(|((this, _), _)| match this.error { @@ -626,23 +627,84 @@ where self.index = 0; E::ready((self, visitor)) - .as_ctx( - #[inline(always)] - |(this, visitor)| { + .as_ctx(|(this, visitor)| { + visit_request_hint::<E>(visitor.cast(), DynWalker(*this)) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), + }) + .into_erased() + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { visit_sequence::<E>(visitor.cast(), *this) - .map(|result| { - match result { - VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => {} - VisitResult::Control(Flow::Done) => return Ok(()), - VisitResult::Control(Flow::Err) => return Err(()), - } - - Ok(()) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), }) .into_erased() - }, - ) - .map(|(_, value)| value) + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { + visit_value::<_, E>(visitor.cast(), BorrowedStatic(this.value)) + .map(|result| match result { + VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_) => None, + VisitResult::Control(Flow::Done) => Some(Ok(())), + VisitResult::Control(Flow::Err) => Some(Err(())), + }) + .into_erased() + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .as_ctx(|((this, visitor), result)| { + if result.is_some() { + E::ready(None).into_erased() + } else { + visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( + TagConst, + visitor.cast(), + ValueWalker::new(TypeId::of::<I::T>()), + ) + .map(|result| match result { + Err(err) => { + this.error = Some(StructWalkErrorKind::Tag(err)); + Some(Err(())) + } + Ok(VisitResult::Control(Flow::Continue) | VisitResult::Skipped(_)) => None, + Ok(VisitResult::Control(Flow::Done)) => Some(Ok(())), + Ok(VisitResult::Control(Flow::Err)) => Some(Err(())), + }) + .into_erased() + } + }) + .map(|((ctx, result), other)| match (result, other) { + (Some(result), None) => (ctx, Some(result)), + (None, Some(result)) => (ctx, Some(result)), + (Some(_), Some(_)) => unreachable!(), + (None, None) => (ctx, None), + }) + .map(|(_, value)| match value { + None => Ok(()), + Some(value) => value, + }) .into_erased() // E::wrap(async move { diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs index c0cb843..c45a78f 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::{ErasedEffective, Effect, Effective}, + effect::{blocking::Blocking, Effect, Effective, ErasedEffective}, protocol::{ visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult}, DynVisitor, @@ -17,9 +17,9 @@ use treaty::{ Build, Builder, DefaultMode, Flow, Walk, Walker, }; -// use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker}; -// -// mod common; +use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker}; + +mod common; #[derive(Debug, PartialEq)] struct X { @@ -108,14 +108,16 @@ 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) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> { - todo!() - // E::wrap(async { - // Ok(X { - // a: builders.a.build().await.unwrap(), - // b: builders.b.build().await.unwrap(), - // }) - // }) + fn from_builders<'a>( + builders: Self::Builders, + ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> { + E::from_future(async { + Ok(X { + a: builders.a.build().into_future().await.unwrap(), + b: builders.b.build().into_future().await.unwrap(), + }) + }) + .into_erased() } #[inline(always)] @@ -133,167 +135,174 @@ impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> fo #[inline(always)] fn new_builders<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E> { - todo!() - // E::wrap(async { - // Fields { - // a: Builder::<E>::from_seed(()).await, - // b: Builder::<E>::from_seed(()).await, - // } - // }) + E::from_future(async { + Fields { + a: Builder::<E>::from_seed(()).into_future().await, + b: Builder::<E>::from_seed(()).into_future().await, + } + }) + .into_erased() } } -// #[test] -// #[ignore] -// fn demo() { -// let value = X { a: true, b: false }; -// -// let (other, _) = transform::<StructBuilder<Info, DefaultMode, _>, _, Blocking>( -// (), -// StructWalker::<Info, _, DefaultMode, _>::new(&value), -// ) -// .value(); -// -// assert_eq!(other.unwrap(), value); -// } -// -// #[test] -// fn from_basic_tuple_like() { -// // A tuple like is just a sequence. -// let mut scope = MockSequenceScope::<Blocking>::new(); -// -// // First field. -// scope.expect_next().once().returning(|visitor| { -// // Visit a bool value. -// // -// // The bool visitor should report that it is done. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // We have another field. -// Flow::Continue -// }); -// -// // Second field. -// scope.expect_next().once().returning(|visitor| { -// // Visit a bool value. -// // -// // The bool visitor should report that it is done. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // No more fields. -// Flow::Done -// }); -// -// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); -// let visitor = builder.as_visitor(); -// -// // Visit the sequence of field values. -// assert!(matches!( -// visit_sequence(visitor, &mut scope).value(), -// VisitResult::Control(Flow::Done) -// )); -// -// assert_eq!(builder.build().value().unwrap(), X { a: true, b: false }); -// } -// -// #[test] -// fn from_basic_map_like() { -// // A map is built from a sequence. -// let mut scope = MockSequenceScope::<Blocking>::new(); -// -// // Here we do the b field first to show a map-like doesn't care about order. -// scope.expect_next().once().returning(|mut visitor| { -// let mut walker = MockWalker::<(), ()>::new(); -// -// // We need to give the b field name in the key tag. -// walker.expect_walk().once().returning(|visitor| { -// assert_eq!( -// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// Ok(()) -// }); -// -// // Tag the value with a key as the field name. -// assert_eq!( -// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), -// Ok(VisitResult::Control(Flow::Continue)), -// ); -// -// // Visit the value as normal. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // There is another field. -// Flow::Continue -// }); -// -// // The other field. -// scope.expect_next().once().returning(|mut visitor| { -// let mut walker = MockWalker::<(), ()>::new(); -// -// // Here we do field a. -// walker.expect_walk().once().returning(|visitor| { -// assert_eq!( -// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// Ok(()) -// }); -// -// // Tag the value with a key. -// assert_eq!( -// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), -// Ok(VisitResult::Control(Flow::Continue)), -// ); -// -// // The field value. -// assert_eq!( -// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // The sequence protocol allows for us to wait to decide if there is another item. -// Flow::Continue -// }); -// -// // There are no more fields. -// scope.expect_next().once().returning(|_visitor| Flow::Done); -// -// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); -// let mut visitor = builder.as_visitor(); -// -// // We need to provide the map tag to the struct before getting into the sequence. -// // This tag notifies the struct builder to expect the sequence as a map. -// assert_eq!( -// visit_tag::<tags::Map, Blocking, _>(TagConst, visitor.cast(), NoopWalker::new()).value(), -// Ok(VisitResult::Control(Flow::Continue)) -// ); -// -// // Visit the sequence of fields. -// assert_eq!( -// visit_sequence(visitor, &mut scope).value(), -// VisitResult::Control(Flow::Done) -// ); -// -// // The struct is built as the mock walker above makes it. -// assert_eq!(builder.build().value().unwrap(), X { a: false, b: true }); -// } +#[test] +#[ignore] +fn demo() { + let value = X { a: true, b: false }; + + let (other, _) = transform::<StructBuilder<Info, DefaultMode, _>, _, Blocking>( + (), + StructWalker::<Info, _, DefaultMode, _>::new(&value), + ) + .value(); + + assert_eq!(other.unwrap(), value); +} + +#[test] +fn from_basic_tuple_like() { + // A tuple like is just a sequence. + let mut scope = MockSequenceScope::<Blocking>::new(); + + // First field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + // + // The bool visitor should report that it is done. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), + VisitResult::Control(Flow::Done) + ); + + // We have another field. + Flow::Continue + }); + + // Second field. + scope.expect_next().once().returning(|visitor| { + // Visit a bool value. + // + // The bool visitor should report that it is done. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), + VisitResult::Control(Flow::Done) + ); + + // No more fields. + Flow::Done + }); + + let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); + let visitor = builder.as_visitor(); + + // Visit the sequence of field values. + assert!(matches!( + visit_sequence(visitor, &mut scope).value(), + VisitResult::Control(Flow::Done) + )); + + assert_eq!(builder.build().value().unwrap(), X { a: true, b: false }); +} + +#[test] +fn from_basic_map_like() { + // A map is built from a sequence. + let mut scope = MockSequenceScope::<Blocking>::new(); + + // Here we do the b field first to show a map-like doesn't care about order. + scope.expect_next().once().returning(|mut visitor| { + let mut walker = MockWalker::<(), ()>::new(); + + // We need to give the b field name in the key tag. + walker.expect_walk().once().returning(|visitor| { + assert_eq!( + visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(), + VisitResult::Control(Flow::Done) + ); + + Ok(()) + }); + + // Tag the value with a key as the field name. + assert_eq!( + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), + ); + + // Visit the value as normal. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(), + VisitResult::Control(Flow::Done) + ); + + // There is another field. + Flow::Continue + }); + + // The other field. + scope.expect_next().once().returning(|mut visitor| { + let mut walker = MockWalker::<(), ()>::new(); + + // Here we do field a. + walker.expect_walk().once().returning(|visitor| { + assert_eq!( + visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(), + VisitResult::Control(Flow::Done) + ); + + Ok(()) + }); + + // Tag the value with a key. + assert_eq!( + visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(), + Ok(VisitResult::Control(Flow::Continue)), + ); + + // The field value. + assert_eq!( + visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(), + VisitResult::Control(Flow::Done) + ); + + // The sequence protocol allows for us to wait to decide if there is another item. + Flow::Continue + }); + + // There are no more fields. + scope.expect_next().once().returning(|_visitor| Flow::Done); + + let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value(); + let mut visitor = builder.as_visitor(); + + // We need to provide the map tag to the struct before getting into the sequence. + // This tag notifies the struct builder to expect the sequence as a map. + assert_eq!( + visit_tag::<tags::Map, Blocking, _>(TagConst, visitor.cast(), NoopWalker::new()).value(), + Ok(VisitResult::Control(Flow::Continue)) + ); + + // Visit the sequence of fields. + assert_eq!( + visit_sequence(visitor, &mut scope).value(), + VisitResult::Control(Flow::Done) + ); + + // The struct is built as the mock walker above makes it. + assert_eq!(builder.build().value().unwrap(), X { a: false, b: true }); +} pub mod demo { use crate::Walk; use macro_rules_attribute::derive; - use treaty::{effect::{r#async::Async, blocking::{BlockOn, Blocking, Spin}, Effective as _}, transform, Build, DefaultMode}; + use treaty::{ + effect::{ + blocking::{BlockOn, Blocking, Spin}, + r#async::Async, + Effective as _, + }, + transform, Build, DefaultMode, + }; #[derive(Walk!, Debug)] pub struct X { diff --git a/tests/common/builder.rs b/tests/common/builder.rs index e12b013..a40e8fa 100644 --- a/tests/common/builder.rs +++ b/tests/common/builder.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::DynVisitor, Builder, BuilderTypes, }; @@ -49,18 +49,18 @@ impl<Seed: 'static, Value: 'static, Error: 'static> MockBuilder<Seed, Value, Err impl<'ctx, Seed: Send + Sync, Value: Send + Sync, Error: Send + Sync, E: Effect> Builder<'ctx, E> for MockBuilder<Seed, Value, Error> { - fn from_seed<'a>(seed: Self::Seed) -> Future<'a, Self, E> + fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E> where Self: 'a, { - E::ready(Self::from_seed(seed)) + E::ready(Self::from_seed(seed)).into_erased() } - fn build<'a>(self) -> Future<'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.build()) + E::ready(self.build()).into_erased() } fn as_visitor(&mut self) -> DynVisitor<'_, 'ctx> { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 544e54d..5b35ce8 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -9,7 +9,7 @@ use std::{ sync::{Mutex, MutexGuard, OnceLock, RwLock}, }; -use treaty::effect::{BlockOn, Spin}; +use treaty::effect::blocking::{BlockOn, Spin}; pub mod builder; pub mod protocol; diff --git a/tests/common/protocol/hint.rs b/tests/common/protocol/hint.rs index 07c7c41..5809380 100644 --- a/tests/common/protocol/hint.rs +++ b/tests/common/protocol/hint.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{any_trait, TypeName}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::{ walker::hint::{Hint, HintMeta, HintProto, MetaHint, MetaKnown}, DynVisitor, @@ -32,14 +32,14 @@ impl<'ctx, P: HintMeta> Hint<'ctx, P> for MockHintWalker<P> { &'a mut self, visitor: DynVisitor<'a, 'ctx>, hint: MetaHint<'a, 'ctx, P>, - ) -> Future<'a, Flow, P::Effect> { - P::Effect::ready(self.hint(visitor, hint)) + ) -> ErasedEffective<'a, Flow, P::Effect> { + P::Effect::ready(self.hint(visitor, hint)).into_erased() } fn known<'a>( &'a mut self, hint: &'a MetaHint<'a, 'ctx, P>, - ) -> Future<'a, Result<MetaKnown<'a, 'ctx, P>, ()>, P::Effect> { - P::Effect::ready(Self::known(self)(&(), hint)) + ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, P>, ()>, P::Effect> { + P::Effect::ready(Self::known(self)(&(), hint)).into_erased() } } diff --git a/tests/common/protocol/recoverable.rs b/tests/common/protocol/recoverable.rs index f1dab5c..47c6d21 100644 --- a/tests/common/protocol/recoverable.rs +++ b/tests/common/protocol/recoverable.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{any_trait, TypeName}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::{ visitor::{DynRecoverableScope, Recoverable, RecoverableProto, RecoverableScope}, DynWalker, @@ -39,19 +39,22 @@ impl<'ctx, E: Effect> Recoverable<'ctx, E> for MockRecoverableVisitor<E> { fn visit<'a>( &'a mut self, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> Future<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E> { - E::ready(self.visit()(&(), scope)) + ) -> ErasedEffective<'a, VisitResult<DynRecoverableScope<'a, 'ctx, E>>, E> { + E::ready(self.visit()(&(), scope)).into_erased() } } mock! { pub RecoverableScopeVisitor<E> { - pub fn new_walk<'a, 'ctx>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> Status; + pub fn new_walk<'a, 'b, 'ctx>(&'a mut self, visitor: DynVisitor<'b, 'ctx>) -> Status; } } impl<'ctx, E: Effect> RecoverableScope<'ctx, E> for MockRecoverableScopeVisitor<E> { - fn new_walk<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> Future<'a, Status, E> { - E::ready(self.new_walk(visitor)) + fn new_walk<'a: 'c, 'b: 'c, 'c>( + &'a mut self, + visitor: DynVisitor<'b, 'ctx>, + ) -> ErasedEffective<'c, Status, E> { + E::ready(self.new_walk(visitor)).into_erased() } } diff --git a/tests/common/protocol/request_hint.rs b/tests/common/protocol/request_hint.rs index be203b3..012ca99 100644 --- a/tests/common/protocol/request_hint.rs +++ b/tests/common/protocol/request_hint.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{any_trait, TypeName}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::visitor::{RequestHint, RequestHintProto, Value, ValueProto, VisitResult}, protocol::DynWalker, Flow, @@ -27,7 +27,7 @@ impl<'ctx, E: Effect> RequestHint<'ctx, E> for MockRequestHintVisitor<E> { fn request_hint<'a>( &'a mut self, walker: DynWalker<'a, 'ctx>, - ) -> Future<'a, VisitResult<DynWalker<'a, 'ctx>>, E> { - E::ready(self.request_hint()(&(), walker)) + ) -> ErasedEffective<'a, VisitResult<DynWalker<'a, 'ctx>>, E> { + E::ready(self.request_hint()(&(), walker)).into_erased() } } diff --git a/tests/common/protocol/sequence.rs b/tests/common/protocol/sequence.rs index f4f0abf..9b3f6b2 100644 --- a/tests/common/protocol/sequence.rs +++ b/tests/common/protocol/sequence.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{any_trait, TypeName}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::DynWalker, protocol::{ visitor::{ @@ -35,8 +35,8 @@ impl<'ctx, E: Effect> Sequence<'ctx, E> for MockSequenceVisitor<E> { fn visit<'a>( &'a mut self, scope: DynSequenceScope<'a, 'ctx, E>, - ) -> Future<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> { - E::ready(self.visit()(&(), scope)) + ) -> ErasedEffective<'a, VisitResult<DynSequenceScope<'a, 'ctx, E>>, E> { + E::ready(self.visit()(&(), scope)).into_erased() } } @@ -48,11 +48,11 @@ mock! { } impl<'ctx, E: Effect> SequenceScope<'ctx, E> for MockSequenceScope<E> { - fn size_hint(&mut self) -> Future<'_, (usize, Option<usize>), E> { - E::ready(self.size_hint()) + fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> { + E::ready(self.size_hint()).into_erased() } - fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> Future<'a, Flow, E> { - E::ready(self.next(visitor)) + fn next<'a>(&'a mut self, visitor: DynVisitor<'a, 'ctx>) -> ErasedEffective<'a, Flow, E> { + E::ready(self.next(visitor)).into_erased() } } diff --git a/tests/common/protocol/tag.rs b/tests/common/protocol/tag.rs index 581cced..9d2f98a 100644 --- a/tests/common/protocol/tag.rs +++ b/tests/common/protocol/tag.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::any_trait, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::visitor::{Tag, TagKind, TagProto, VisitResult}, DynWalkerObjSafe, }; @@ -21,14 +21,15 @@ any_trait! { } impl<'ctx, K: TagKind, E: Effect> Tag<'ctx, K, E> for MockTagVisitor<K, E> { - fn visit<'a>( + fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, kind: K, - walker: DynWalkerObjSafe<'a, 'ctx, E>, - ) -> Future<'a, VisitResult<DynWalkerObjSafe<'a, 'ctx, E>>, E> { + walker: DynWalkerObjSafe<'b, 'ctx, E>, + ) -> ErasedEffective<'c, VisitResult<DynWalkerObjSafe<'b, 'ctx, E>>, E> { E::ready(match self.visit(kind, walker) { VisitResult::Skipped(_) => VisitResult::Skipped(walker), VisitResult::Control(flow) => VisitResult::Control(flow), }) + .into_erased() } } diff --git a/tests/common/protocol/visitor.rs b/tests/common/protocol/visitor.rs index f19b045..fdc9921 100644 --- a/tests/common/protocol/visitor.rs +++ b/tests/common/protocol/visitor.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{any_trait, TypeName}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::visitor::{Value, ValueProto, VisitResult}, Flow, }; @@ -31,7 +31,7 @@ where fn visit<'a>( &'a mut self, value: TypeName::T<'a, 'ctx, T>, - ) -> Future<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E> + ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E> where TypeName::T<'a, 'ctx, T>: Send, 'ctx: 'a, @@ -40,5 +40,6 @@ where VisitResult::Skipped(_) => VisitResult::Skipped(value), VisitResult::Control(flow) => VisitResult::Control(flow), }) + .into_erased() } } diff --git a/tests/common/walker.rs b/tests/common/walker.rs index b1064f6..e4e879e 100644 --- a/tests/common/walker.rs +++ b/tests/common/walker.rs @@ -1,7 +1,7 @@ use mockall::mock; use treaty::{ any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, - effect::{Effect, Future}, + effect::{Effect, Effective, ErasedEffective}, protocol::DynVisitor, Builder, BuilderTypes, Walker, WalkerTypes, }; @@ -24,14 +24,14 @@ impl<Output: Send + Sync, Error: Send + Sync> WalkerTypes for MockWalker<Output, impl<'ctx, Output: Send + Sync, Error: Send + Sync, E: Effect> Walker<'ctx, E> for MockWalker<Output, Error> { - fn walk<'a>( + fn walk<'a: 'c, 'c>( self, visitor: DynVisitor<'a, 'ctx>, - ) -> Future<'a, Result<Self::Output, Self::Error>, E> + ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> where - Self: 'a, + Self: 'c, { - E::ready(self.walk(visitor)) + E::ready(self.walk(visitor)).into_erased() } } diff --git a/tests/protocol_visitor_recoverable.rs b/tests/protocol_visitor_recoverable.rs index 6b70906..a0a0b95 100644 --- a/tests/protocol_visitor_recoverable.rs +++ b/tests/protocol_visitor_recoverable.rs @@ -1,7 +1,7 @@ use common::protocol::recoverable::MockRecoverableVisitor; use treaty::{ any::OwnedStatic, - effect::{Blocking, ReadyValue}, + effect::blocking::Blocking, protocol::{ visitor::{Recoverable, ValueProto, VisitResult}, DynVisitor, diff --git a/tests/protocol_visitor_request_hint.rs b/tests/protocol_visitor_request_hint.rs index 6c6c2fb..dee681d 100644 --- a/tests/protocol_visitor_request_hint.rs +++ b/tests/protocol_visitor_request_hint.rs @@ -10,7 +10,7 @@ use common::{ use mockall::predicate::eq; use treaty::{ any::{OwnedStatic, TypeNameId}, - effect::{Blocking, ReadyValue}, + effect::blocking::Blocking, protocol::{ visitor::{RequestHint, RequestHintProto, ValueKnown, ValueProto, VisitResult}, walker::hint::HintProto, diff --git a/tests/protocol_visitor_sequence.rs b/tests/protocol_visitor_sequence.rs index 8657daf..732e090 100644 --- a/tests/protocol_visitor_sequence.rs +++ b/tests/protocol_visitor_sequence.rs @@ -3,7 +3,7 @@ use std::any::TypeId; use common::protocol::sequence::{MockSequenceScope, MockSequenceVisitor, SequenceScopeFactory}; use treaty::{ any::{OwnedStatic, TypeNameId}, - effect::{Blocking, ReadyValue}, + effect::blocking::Blocking, protocol::{ visitor::{Sequence, SequenceProto, ValueProto, VisitResult}, DynVisitor, diff --git a/tests/protocol_visitor_tag.rs b/tests/protocol_visitor_tag.rs index cf052c4..fa1cfd3 100644 --- a/tests/protocol_visitor_tag.rs +++ b/tests/protocol_visitor_tag.rs @@ -3,7 +3,7 @@ use std::any::TypeId; use common::protocol::tag::MockTagVisitor; use treaty::{ any::{OwnedStatic, TypeNameId}, - effect::{Blocking, ReadyValue}, + effect::blocking::Blocking, protocol::{ visitor::{Tag, TagConst, TagDyn, TagProto, ValueProto, VisitResult}, DynVisitor, diff --git a/tests/protocol_visitor_value.rs b/tests/protocol_visitor_value.rs index 91fb280..f24dc5e 100644 --- a/tests/protocol_visitor_value.rs +++ b/tests/protocol_visitor_value.rs @@ -10,7 +10,7 @@ use treaty::{ AnyTrait, BorrowedStatic, BorrowedStaticHrt, OwnedStatic, TempBorrowedMutStatic, TempBorrowedMutStaticHrt, TypeNameId, }, - effect::{Blocking, ReadyValue}, + effect::blocking::Blocking, protocol::{ visitor::{visit_value, Value, ValueKnown, ValueProto, VisitResult}, walker::hint::Hint, diff --git a/tests/protocol_walker_hint.rs b/tests/protocol_walker_hint.rs index 75c8d94..4928752 100644 --- a/tests/protocol_walker_hint.rs +++ b/tests/protocol_walker_hint.rs @@ -3,7 +3,10 @@ use std::any::TypeId; use common::protocol::hint::MockHintWalker; use treaty::{ any::TypeNameId, - effect::{Blocking, Effect, Future, ReadyValue, Spin}, + effect::{ + blocking::{Blocking, Spin}, + Effect, Effective, ErasedEffective, + }, hkt::higher_ranked_type, protocol::{ walker::hint::{self, Hint, HintMeta, HintProto, Meta, MetaKnown}, @@ -109,14 +112,14 @@ fn known_can_have_temp_mutable_borrow() { &'a mut self, _visitor: DynVisitor<'a, 'ctx>, _hint: <MyProtocol as HintMeta>::Hint, - ) -> Future<'a, Flow, Blocking> { + ) -> ErasedEffective<'a, Flow, Blocking> { unreachable!() } fn known<'a>( &'a mut self, (): &'a <MyProtocol as HintMeta>::Hint, - ) -> Future<'a, Result<MetaKnown<'a, 'ctx, MyProtocol>, ()>, Blocking> { + ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, MyProtocol>, ()>, Blocking> { self.0.push_str("test"); Blocking::<Spin>::ready(Ok(Known(self.0))) @@ -168,14 +171,14 @@ fn known_can_have_context_borrow() { &'a mut self, _visitor: DynVisitor<'a, 'ctx>, _hint: <MyProtocol as HintMeta>::Hint, - ) -> Future<'a, Flow, Blocking> { + ) -> ErasedEffective<'a, Flow, Blocking> { unreachable!() } fn known<'a>( &'a mut self, (): &'a <MyProtocol as HintMeta>::Hint, - ) -> Future<'a, Result<MetaKnown<'a, 'ctx, MyProtocol>, ()>, Blocking> { + ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, MyProtocol>, ()>, Blocking> { Blocking::<Spin>::ready(Ok(Known(self.0))) } } diff --git a/tests/walker_struct.rs b/tests/walker_struct.rs index 95184a3..4ff61d1 100644 --- a/tests/walker_struct.rs +++ b/tests/walker_struct.rs @@ -1,7 +1,7 @@ use mockall::predicate::eq; use treaty::{ any::{BorrowedStatic, BorrowedStaticHrt, OwnedStatic, TypeNameId}, - effect::{Blocking, Effect, Future, ReadyValue}, + effect::{blocking::Blocking, Effect, Effective, ErasedEffective}, protocol::{ visitor::{tags, SequenceProto, TagConst, TagProto, ValueProto, VisitResult}, DynVisitor, @@ -44,8 +44,8 @@ impl<'ctx, M> StructTypeInfo<'ctx, M> for Info { index: usize, value: &'ctx Self::T, mut visitor: DynVisitor<'a, 'ctx>, - ) -> Future<'a, Result<Flow, Self::FieldError>, E> { - E::wrap(async move { + ) -> ErasedEffective<'a, Result<Flow, Self::FieldError>, E> { + E::from_future(async move { match index { // A real impl would be expected to tag these values with the field name. 0 => { @@ -55,7 +55,10 @@ impl<'ctx, M> StructTypeInfo<'ctx, M> for Info { .unwrap(); // Emit the field value. - assert_eq!(obj.visit(OwnedStatic(value.a)).await, Flow::Done.into()); + assert_eq!( + obj.visit(OwnedStatic(value.a)).into_future().await, + Flow::Done.into() + ); // There are more fields. Ok(Flow::Continue) @@ -67,7 +70,10 @@ impl<'ctx, M> StructTypeInfo<'ctx, M> for Info { .unwrap(); // Emit the field value. - assert_eq!(obj.visit(OwnedStatic(value.b)).await, Flow::Done.into()); + assert_eq!( + obj.visit(OwnedStatic(value.b)).into_future().await, + Flow::Done.into() + ); // There are no more fields. Ok(Flow::Done) @@ -75,6 +81,7 @@ impl<'ctx, M> StructTypeInfo<'ctx, M> for Info { _ => Ok(Flow::Done), } }) + .into_erased() } } |