Diffstat (limited to 'src/effect/blocking.rs')
-rw-r--r--src/effect/blocking.rs269
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())
}
}