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
use crate::{Context, Effectful, Event, Poll};
use std::pin::Pin;
pub enum NextEvent<C: Effectful> {
Computation(C),
Event(Event<C::Output, C::Effect>),
Gone,
}
impl<C: Effectful> NextEvent<C> {
pub fn occured(&self) -> bool {
match self {
NextEvent::Computation(_) => false,
_ => true,
}
}
pub fn take_event(self: Pin<&mut Self>) -> Option<Event<C::Output, C::Effect>> {
unsafe {
let this = self.get_unchecked_mut();
match this {
NextEvent::Event(_) => {
let ret = match std::mem::replace(this, NextEvent::Gone) {
NextEvent::Event(ev) => ev,
_ => unreachable!(),
};
Some(ret)
}
_ => None,
}
}
}
}
impl<C: Effectful> Effectful for NextEvent<C> {
type Output = ();
type Effect = !;
#[inline]
fn poll(self: Pin<&mut Self>, cx: &Context) -> Poll<Self::Output, Self::Effect> {
unsafe {
let this = self.get_unchecked_mut();
match this {
NextEvent::Computation(ref mut c) => match Pin::new_unchecked(c).poll(cx) {
Poll::Event(ev) => {
*this = NextEvent::Event(ev);
Poll::complete(())
}
Poll::Pending => Poll::Pending,
},
_ => Poll::complete(()),
}
}
}
}