1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use core::ops::ControlFlow;

use crate::effect::{Effective, ErasedEffective, Ss};

use super::{Async, BoxOrReady};

pub struct Value<T>(pub T);

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)
    }

    type Effect = Async;

    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>
        = 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: 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,
    {
        BoxOrReady::Boxed(Box::pin(async move {
            let mut this = self.into_future().await;

            loop {
                if let ControlFlow::Break(value) = cb(&mut this).into_future().await {
                    return (this, value);
                }
            }
        }))
    }

    type Map<'a, T: Ss + 'a, F: Ss + 'a>
        = Value<T>
    where
        F: FnOnce(Self::Output) -> T,
        'lt: 'a;

    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,
    {
        Value(cb(self.0))
    }

    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: 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,
    {
        cb(self.0)
    }

    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: 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 ())>,
        'lt: 'a,
    {
        BoxOrReady::Boxed(Box::pin(async {
            let mut this = self.0;

            let result = cb(&mut this).into_future().await;

            (this, result)
        }))
    }
}