mod spin;
pub use spin::*;
use crate::hkt::Marker;
use super::*;
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 = Spin>(Marker<B>);
#[repr(transparent)]
pub struct Value<T, B>(pub T, Marker<B>);
impl<T, B> Value<T, B> {
pub fn value(self) -> T {
self.0
}
}
impl<'lt, T: Ss, B: BlockOn, O> Erased::ForLt<'lt, T, Blocking<B>, &'lt (T, O)> for Value<T, B> {
type Effective = Value<T, B>;
}
impl<T: Ss, B: BlockOn> Erased::Hkt<T, Blocking<B>> for Value<T, B> {
type Hrt<O> = Self;
}
impl<B: BlockOn> Effect for Blocking<B> {
type Erased<T: Ss> = Value<T, B>;
// type Ready<'a, T: Ss + 'a> = Value<T, B>;
fn ready<'a, T: Ss + 'a>(value: T) -> ErasedEffective<'a, T, Self> {
Value(value, Default::default())
}
// type FromFuture<'a, F: Ss + 'a> = Value<F::Output, B>
// where
// F: Future,
// F::Output: Ss + 'a;
fn from_future<'a, F: Ss + 'a>(future: F) -> ErasedEffective<'a, F::Output, Self>
where
F: Future,
F::Output: Ss + 'a,
{
Value(B::block_on(future), Default::default())
}
}
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
}
type Effect = Blocking<B>;
type Output = U;
type IntoFuture = core::future::Ready<U>;
fn into_future(self) -> Self::IntoFuture {
core::future::ready(self.0)
}
// type Loop<'ctx: 'a, 'a, T: 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: 'lt, 'wrap, T: Ss, F: Ss>(
self,
mut cb: F,
) -> ErasedEffective<'wrap, (Self::Output, T), Self::Effect>
where
F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect>,
{
let mut this = self.0;
loop {
if let ControlFlow::Break(value) = cb(&mut this).0 {
return Value((this, value), Default::default());
}
}
}
// type Map<'a, T: Ss + 'a, F: Ss + 'a> = Value<T, B>
// where
// F: FnOnce(Self::Output) -> T,
// 'lt: 'a;
fn map<'wrap, T: Ss, F: Ss>(self, cb: F) -> ErasedEffective<'wrap, T, Self::Effect>
where
F: FnOnce(Self::Output) -> T,
'lt: 'wrap,
{
Value(cb(self.0), Default::default())
}
// 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: Ss, F: Ss>(self, cb: F) -> ErasedEffective<'a, T, Self::Effect>
where
F: FnOnce(Self::Output) -> ErasedEffective<'a, T, Self::Effect>,
'lt: 'a,
{
cb(self.0).into_erased::<()>()
}
// 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: 'lt, 'wrap, T: Ss, S: Ss, C: Ss, K: Ss, F: Ss, A: Ss, R: Ss>(
self,
split: S,
cb: F,
after: A,
) -> ErasedEffective<'wrap, R, Self::Effect>
where
S: FnOnce(Self::Output) -> (C, K),
F: for<'b> FnOnce(&'b mut C, K) -> ErasedEffective<'b, T, Self::Effect>,
A: FnOnce(C, T) -> R,
{
let (mut this, owned) = split(self.0);
let result = cb(&mut this, owned).0;
Value(after(this, result), Default::default())
}
}
impl<B: BlockOn> Join for Blocking<B> {
type Effect = Blocking<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: 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: 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>,
{
let v0 = cb.0.into_erased::<()>().0;
let v1 = cb.1.into_erased::<()>().0;
Value((v0, v1), Default::default())
}
fn three<'a, T0: Ss + 'a, T1: Ss + 'a, T2: Ss + 'a>(
cb: (T0, T1, T2),
) -> Self::Three<'a, T0, T1, T2>
where
T0: Effective<'a, Effect = Self::Effect>,
T1: Effective<'a, Effect = Self::Effect>,
T2: Effective<'a, Effect = Self::Effect>,
{
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<B: BlockOn> TryJoin for Blocking<B> {
type Effect = Blocking<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: 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: Ss + 'a, T1: Ss + 'a, F0: Ss + 'a, F1: Ss + 'a>(
cb: (F0, F1),
) -> Self::Two<'a, T0, T1>
where
T0: TryEffective<'a, Effect = Self::Effect>,
T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>,
F0: FnOnce() -> T0,
F1: FnOnce() -> T1,
{
let v0 = match (cb.0)().into_erased::<()>().0 {
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()),
};
Value(Ok((v0, v1)), Default::default())
}
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
T0: TryEffective<'a, Effect = Self::Effect>,
T1: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>,
T2: TryEffective<'a, Err = T0::Err, Effect = Self::Effect>,
F0: FnOnce() -> T0,
F1: FnOnce() -> T1,
F2: FnOnce() -> T2,
{
let v0 = match (cb.0)().into_erased::<()>().0 {
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())
}
}