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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use core::ops::ControlFlow;

use futures::Future;

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

use super::{Async, BoxOrReady, Map, Then};

pub struct Shim<F> {
    future: F,
}

impl<F> Shim<F> {
    pub(super) fn new(future: F) -> Self {
        Self { future }
    }
}

impl<'lt, U: Send + Sync + 'lt> Effective<'lt> for Shim<U>
where
    U: Future,
    U::Output: Send + Sync + 'lt,
{
    fn into_erased<B>(self) -> ErasedEffective<'lt, Self::Output, Self::Effect, B> {
        BoxOrReady::Boxed(Box::pin(self.future))
    }

    type Effect = Async;

    type Output = U::Output;

    type IntoFuture = U;

    fn into_future(self) -> Self::IntoFuture {
        self.future
    }

    type Loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
        = BoxOrReady<'a, (U::Output, T)>
    where
        F: for<'b> FnMut(&'b mut Self::Output) -> ErasedEffective<'b, ControlFlow<T>, Self::Effect, (&'b mut Self::Output, &'ctx ())>,
        'lt: 'a;

    fn r#loop<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + '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, (&'b mut Self::Output, &'ctx ())>,
        '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: Send + Sync + 'a, F: Send + Sync + 'a>
        = Map<U, F>
    where
        F: FnOnce(Self::Output) -> T,
        'lt: 'a;

    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,
        'lt: 'a,
    {
        Map::new(self.future, cb)
    }

    type Then<'a, T: Send + Sync + 'a, V: Send + Sync + 'a, F: Send + Sync + 'a>
        = Then<'a, U, F, V>
    where
        F: FnOnce(Self::Output) -> V,
        V: Effective<'a, Output = T, Effect = Self::Effect>,
        'lt: 'a;

    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<'a, Output = T, Effect = Self::Effect>,
        'lt: 'a,
    {
        Then::new(self.future, cb)
    }

    type AsCtx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>
        = BoxOrReady<'a, (Self::Output, T)>
    where
        F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>,
        'lt: 'a;

    fn as_ctx<'ctx: 'a, 'a, T: Send + Sync + 'a, F: Send + Sync + 'a>(self, cb: F) -> Self::AsCtx<'ctx, 'a, T, F>
    where
        F: for<'b> FnOnce(&'b mut Self::Output) -> ErasedEffective<'b, T, Self::Effect>,
        'lt: 'a,
    {
        BoxOrReady::Boxed(Box::pin(async {
            let mut this = self.future.await;

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

            (this, result)
        }))
    }
}