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
113
114
115
116
117
118
119
120
121
use_prelude!();
pub
struct ItemSlot<'item_slot, Item : 'item_slot> (
Pin<&'item_slot CellOption<Item>>,
);
impl<'item_slot, Item : 'item_slot> From<Pin<&'item_slot CellOption<Item>>>
for ItemSlot<'item_slot, Item>
{
#[inline]
fn from (p: Pin<&'item_slot CellOption<Item>>)
-> Self
{
Self(p)
}
}
impl<Item> Clone for ItemSlot<'_, Item> {
#[inline]
fn clone (self: &'_ Self)
-> Self
{
let Self(ref inner) = *self;
Self(*inner)
}
}
#[pin_project]
pub
struct Generator<'item_slot, Item : 'item_slot, F : Future> {
item_slot: ItemSlot<'item_slot, Item>,
#[pin]
future: F,
}
impl<'item_slot, Item : 'item_slot, F : Future> Generator<'item_slot, Item, F> {
pub
fn new<Args> (
item_slot: ItemSlot<'item_slot, Item>,
factory: impl FnOnce(Coroutine<'item_slot, Item>, Args) -> F,
args: Args,
) -> Self
{
Self {
future: factory(Coroutine { item_slot: item_slot.clone() }, args),
item_slot,
}
}
pub
fn resume (self: Pin<&'_ mut Self>)
-> GeneratorState<Item, F::Output>
{
let this = self.project();
create_context!(cx);
match this.future.poll(&mut cx) {
| Poll::Pending => {
let value =
this.item_slot
.0
.take()
.expect("Missing item in item_slot!")
;
GeneratorState::Yield(value)
},
| Poll::Ready(value) => {
GeneratorState::Return(value)
}
}
}
}
#[derive(
Debug,
Clone, Copy,
PartialEq, Eq,
)]
pub
enum GeneratorState<Yield, Return = ()> {
Yield(Yield),
Return(Return),
}
pub
struct Coroutine<'item_slot, Item : 'item_slot> {
item_slot: ItemSlot<'item_slot, Item>,
}
impl<'slot_item, Item> Coroutine<'slot_item, Item> {
pub
fn _yield (self: &'_ Self, value: Item)
-> impl Future<Output = ()> + '_
{
let Self { ref item_slot, .. } = *self;
let _ = item_slot.0.set(value);
WaitForClear { item_slot }
}
}
struct WaitForClear<'item_slot, Item : 'item_slot> {
item_slot: &'item_slot ItemSlot<'item_slot, Item>,
}
impl<'item_slot, Item> Future for WaitForClear<'item_slot, Item>
{
type Output = ();
fn poll (self: Pin<&'_ mut Self>, _: &'_ mut Context<'_>)
-> Poll<()>
{
if self.item_slot.0.is_some() {
Poll::Pending
} else {
Poll::Ready(())
}
}
}