Diffstat (limited to 'src/effect/blocking.rs')
| -rw-r--r-- | src/effect/blocking.rs | 269 |
1 files changed, 179 insertions, 90 deletions
diff --git a/src/effect/blocking.rs b/src/effect/blocking.rs index ea97477..abadfb2 100644 --- a/src/effect/blocking.rs +++ b/src/effect/blocking.rs @@ -1,164 +1,253 @@ +mod spin; + +pub use spin::*; + +use crate::hkt::Marker; + use super::*; -pub enum Blocking {} +pub trait BlockOn: 'static { + fn block_on<F>(future: F) -> F::Output + where + F: core::future::Future + Send, + <F as core::future::Future>::Output: Send; +} + +pub struct Blocking<B>(Marker<B>); -pub struct Value<T>(pub T); +#[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> { + type T = Value<T, B>; +} -impl Effect for Blocking { - type Erased<T> = Value<T>; +impl<B: BlockOn> Effect for Blocking<B> { + type Erased<T: Send + Sync> = Value<T, B>; - type Ready<T> = Value<T>; + type Ready<'a, T: Send + Sync + 'a> = Value<T, B>; - fn ready<T>(value: T) -> Self::Ready<T> { - todo!() + fn ready<'a, T: Send + Sync + 'a>(value: T) -> Self::Ready<'a, T> { + Value(value, Default::default()) } - type FromFuture<F> = Value<F::Output> + type FromFuture<'a, F: Send + Sync + 'a> = Value<F::Output, B> where - F: Future; + F: Future, + F::Output: Send + Sync + 'a; - fn from_future<F>() -> Self::FromFuture<F> + fn from_future<'a, F: Send + Sync + 'a>(future: F) -> Self::FromFuture<'a, F> where F: Future, + F::Output: Send + Sync + 'a, { - todo!() + Value(B::block_on(future), Default::default()) } } -impl<U> Effective for Value<U> { - type Effect = Blocking; +impl<'lt, U: Send + Sync + 'lt, B: BlockOn> Effective<'lt> for Value<U, B> { + fn into_erased(self) -> ErasedEffective<'lt, Self::Output, Self::Effect> { + self + } + + type Effect = Blocking<B>; type Output = U; type IntoFuture = core::future::Ready<U>; fn into_future(self) -> Self::IntoFuture { - todo!() - } - - type Loop<T, V, F> = Value<T> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>; - - fn r#loop<T, V, F>(self, cb: F) -> Self::Loop<T, V, F> - where - F: for<'a> FnMut(&'a mut Self::Output) -> EffectiveT<'a, V, ControlFlow<T>, Self::Effect>, - V: EffectiveHrt<ControlFlow<T>, Self::Effect>, - { - todo!() + core::future::ready(self.0) } - type Map<T, F> = Value<T> + type Map<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<T, B> where F: FnOnce(Self::Output) -> T; - fn map<T, F>(self, cb: F) -> Self::Map<T, F> + 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!() + Value(cb(self.0), Default::default()) } - type Then<T, V, F> = Value<T> + 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<Output = T, Effect = Self::Effect>; + V: Effective<'a, Output = T, Effect = Self::Effect>; - fn then<T, V, F>(self, cb: F) -> Self::Then<T, V, F> + 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<Output = T, Effect = Self::Effect>, + V: Effective<'a, Output = T, Effect = Self::Effect>, { - todo!() + cb(self.0).into_erased() } - type AsCtx<T, V, F> = Value<T> + type AsCtx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a> = Value<(U, T), B> where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>; + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a; - fn as_ctx<T, V, F>(self, cb: F) -> Self::AsCtx<T, V, F> + fn as_ctx<'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'a, T, F> where - F: for<'a> FnOnce(&'a mut Self::Output) -> EffectiveT<'a, V, T, Self::Effect>, - V: EffectiveHrt<T, Self::Effect>, + F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>, + 'lt: 'a, { - todo!() + let mut this = self.0; + let result = cb(&mut this).0; + Value((this, result), Default::default()) } } -impl Join for Blocking { - type Effect = Self; +impl<B: BlockOn> Join for Blocking<B> { + type Effect = Blocking<B>; - type Two<T0, T1> = Value<(T0::Output, T1::Output)> + type Two<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a> = Value<(T0::Output, T1::Output), B> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>; + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>; - type Three<T0, T1, T2> = Value<(T0::Output, T1::Output, T2::Output)> + type Three<'a, T0: Send + Sync + 'a, T1: Send + Sync + 'a, T2: Send + Sync + 'a> = Value<(T0::Output, T1::Output, T2::Output), B> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>; + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, + T2: Effective<'a, Effect = Self::Effect>; - fn two<T0, T1, F0, F1>(cb: (F0, F1)) -> Self::Two<T0, T1> + 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> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, + T0: Effective<'a, Effect = Self::Effect>, + T1: Effective<'a, Effect = Self::Effect>, F0: FnOnce() -> T0, F1: FnOnce() -> T1, { - todo!() + let v0 = (cb.0)().into_erased().0; + let v1 = (cb.1)().into_erased().0; + + Value((v0, v1), Default::default()) } - fn three<T0, T1, T2, F0, F1, F2>(effectives: (F0, F1, F2)) -> Self::Three<T0, T1, T2> + 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), + ) -> Self::Three<'a, T0, T1, T2> where - T0: Effective<Effect = Self::Effect>, - T1: Effective<Effect = Self::Effect>, - T2: Effective<Effect = Self::Effect>, + 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, { - todo!() + 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()) } } -impl TryJoin for Blocking { - type Effect = Self; - - type Two<Err, V0, V1, T0, T1> = Value<Result<(T0, T1), Err>> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>; +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> + where + V0: Effective<'a, Output = Result<T0, Err>, Effect = Self::Effect>, + V1: Effective<'a, Output = Result<T1, 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> + 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>; + + 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> + 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, + { + let v0 = match (cb.0)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; - type Three<Err, V0, V1, V2, T0, T1, T2> = Value<Result<(T0, T1, T2), Err>> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>; + let v1 = match (cb.1)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; - fn two<Err, T0, T1, V0, V1, F0, F1>(cb: (F0, F1)) -> Self::Two<Err, V0, V1, T0, T1> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - { - todo!() + Value(Ok((v0, v1)), Default::default()) } - fn three<Err, T0, T1, T2, V0, V1, V2, F0, F1, F2>( + 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<Err, V0, V1, V2, T0, T1, T2> - where - V0: Effective<Output = Result<T0, Err>, Effect = Self::Effect>, - V1: Effective<Output = Result<T1, Err>, Effect = Self::Effect>, - V2: Effective<Output = Result<T2, Err>, Effect = Self::Effect>, - F0: FnOnce() -> T0, - F1: FnOnce() -> T1, - F2: FnOnce() -> T2, + ) -> 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, { - todo!() + 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 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; + + let v2 = match (cb.2)().into_erased().0 { + Ok(v) => v, + Err(err) => return Value(Err(err), Default::default()), + }; + + Value(Ok((v0, v1, v2)), Default::default()) } } |