mod spin; pub use spin::*; use crate::hkt::Marker; use super::*; pub struct Blocking(Marker); #[must_use] #[repr(transparent)] pub struct Value(pub T, Marker); impl Value { pub fn value(self) -> T { self.0 } } impl<'lt, T: Ss, B: BlockOn, O> Erased::ForLt<'lt, T, Blocking, &'lt (T, O)> for Value { type Effective = Value; } impl Erased::Hkt> for Value { type Hrt = Self; } impl Effect for Blocking { type BlockOn = B; type Erased = Value; fn ready<'a, T: Ss + 'a>(value: T) -> ErasedEffective<'a, T, Self> { Value(value, Default::default()) } fn from_future<'a, F>(future: F) -> ErasedEffective<'a, F::Output, Self> where F: Future + Ss + 'a, F::Output: Ss + 'a, { Value(B::block_on(future), Default::default()) } } impl<'lt, U: Ss + 'lt, B: BlockOn> Effective<'lt> for Value { fn cast<'wrap, X>(self) -> ErasedEffective<'wrap, Self::Output, Self::Effect, X> { self } type Effect = Blocking; type Output = U; type IntoFuture = core::future::Ready; fn into_future(self) -> Self::IntoFuture { core::future::ready(self.0) } #[inline(always)] fn r#do< 'ctx: 'lt, 'wrap, Pre, Ctx, Owned, First, FirstOutput, FirstPost, Done, Extra, Repeat, RepeatOutput, RepeatPost, Post, Return, >( self, pre: Pre, first: First, first_post: FirstPost, mut repeat: Repeat, mut repeat_post: RepeatPost, post: Post, ) -> ErasedEffective<'wrap, Return, Self::Effect> where Pre: Ss + FnOnce(Self::Output) -> (Ctx, ControlFlow), First: Ss + for<'b> FnOnce( &'b mut Ctx, Owned, ) -> ErasedEffective<'b, FirstOutput, Self::Effect, &'wrap ()>, FirstPost: Ss + for<'b> FnOnce(&'b mut Ctx, FirstOutput) -> ControlFlow, Repeat: Ss + for<'b> FnMut( &'b mut Ctx, &'b mut Extra, ) -> ErasedEffective<'b, RepeatOutput, Self::Effect, &'wrap ()>, RepeatPost: Ss + for<'b> FnMut(&'b mut Ctx, &'b mut Extra, RepeatOutput) -> ControlFlow, Post: Ss + FnOnce(Ctx, Option, Done) -> Return, Return: Ss, FirstOutput: Ss, RepeatOutput: Ss, 'lt: 'wrap, { let (ctx, done, extra) = match pre(self.0) { (mut ctx, ControlFlow::Continue(owned)) => { let first_output = first(&mut ctx, owned).0; let (done, extra) = match first_post(&mut ctx, first_output) { ControlFlow::Continue(mut extra) => loop { let repeat_output = repeat(&mut ctx, &mut extra).0; match repeat_post(&mut ctx, &mut extra, repeat_output) { ControlFlow::Continue(()) => {} ControlFlow::Break(done) => break (done, Some(extra)), } }, ControlFlow::Break(done) => (done, None), }; (ctx, done, extra) } (ctx, ControlFlow::Break(done)) => (ctx, done, None), }; Value(post(ctx, extra, done), Default::default()) } fn ready(value: Self::Output) -> Self { Value(value, Default::default()) } } impl Join for Blocking { type Effect = Blocking; fn two<'a, T0, T1>(cb: (T0, T1)) -> Value<(T0::Output, T1::Output), B> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, { let v0 = cb.0.cast::<()>().0; let v1 = cb.1.cast::<()>().0; Value((v0, v1), Default::default()) } fn three<'a, T0, T1, T2>(cb: (T0, T1, T2)) -> Value<(T0::Output, T1::Output, T2::Output), B> where T0: Ss + 'a + Effective<'a, Effect = Self::Effect>, T1: Ss + 'a + Effective<'a, Effect = Self::Effect>, T2: Ss + 'a + Effective<'a, Effect = Self::Effect>, { let v0 = cb.0.cast::<()>().0; let v1 = cb.1.cast::<()>().0; let v2 = cb.2.cast::<()>().0; Value((v0, v1, v2), Default::default()) } } impl TryJoin for Blocking { type Effect = Blocking; fn two<'a, T0, T1, F0, F1>(cb: (F0, F1)) -> Value, B> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, F0: Ss + 'a + FnOnce() -> T0, F1: Ss + 'a + FnOnce() -> T1, { let v0 = match (cb.0)().cast::<()>().0 { Ok(v) => v, Err(err) => return Value(Err(err), Default::default()), }; let v1 = match (cb.1)().cast::<()>().0 { Ok(v) => v, Err(err) => return Value(Err(err), Default::default()), }; Value(Ok((v0, v1)), Default::default()) } fn three<'a, T0, T1, T2, F0, F1, F2>( cb: (F0, F1, F2), ) -> Value, B> where T0: Ss + 'a + TryEffective<'a, Effect = Self::Effect>, T1: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, T2: Ss + 'a + TryEffective<'a, Err = T0::Err, Effect = Self::Effect>, F0: Ss + 'a + FnOnce() -> T0, F1: Ss + 'a + FnOnce() -> T1, F2: Ss + 'a + FnOnce() -> T2, { let v0 = match (cb.0)().cast::<()>().0 { Ok(v) => v, Err(err) => return Value(Err(err), Default::default()), }; let v1 = match (cb.1)().cast::<()>().0 { Ok(v) => v, Err(err) => return Value(Err(err), Default::default()), }; let v2 = match (cb.2)().cast::<()>().0 { Ok(v) => v, Err(err) => return Value(Err(err), Default::default()), }; Value(Ok((v0, v1, v2)), Default::default()) } }