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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use crate::{
FromValue, OwnedMut, OwnedRef, RawOwnedMut, RawOwnedRef, Shared, ToValue, UnsafeFromValue,
Value, VmError,
};
use pin_project::pin_project;
use std::fmt;
use std::future;
use std::pin::Pin;
use std::task::{Context, Poll};
type DynFuture = dyn future::Future<Output = Result<Value, VmError>> + 'static;
pub struct Future {
future: Option<Pin<Box<DynFuture>>>,
}
impl Future {
pub fn new<T, O>(future: T) -> Self
where
T: 'static + future::Future<Output = Result<O, VmError>>,
O: ToValue,
{
Self {
future: Some(Box::pin(async move {
let value = future.await?;
Ok(value.to_value()?)
})),
}
}
pub fn is_completed(&self) -> bool {
self.future.is_none()
}
}
impl future::Future for Future {
type Output = Result<Value, VmError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<Value, VmError>> {
let this = self.get_mut();
let mut future = this.future.take().expect("futures can only be polled once");
match future.as_mut().poll(cx) {
Poll::Ready(result) => Poll::Ready(result),
Poll::Pending => {
this.future = Some(future);
Poll::Pending
}
}
}
}
impl fmt::Debug for Future {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Future")
.field("is_completed", &self.future.is_none())
.finish()
}
}
#[pin_project]
pub struct SelectFuture<T, F> {
data: T,
#[pin]
future: F,
}
impl<T, F> SelectFuture<T, F> {
pub fn new(data: T, future: F) -> Self {
Self { data, future }
}
}
impl<T, F> future::Future for SelectFuture<T, F>
where
T: Copy,
F: future::Future<Output = Result<Value, VmError>>,
{
type Output = Result<(T, Value), VmError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let result = this.future.poll(cx);
match result {
Poll::Ready(result) => match result {
Ok(value) => Poll::Ready(Ok((*this.data, value))),
Err(e) => Poll::Ready(Err(e)),
},
Poll::Pending => Poll::Pending,
}
}
}
impl FromValue for Shared<Future> {
fn from_value(value: Value) -> Result<Self, VmError> {
Ok(value.into_future()?)
}
}
impl FromValue for Future {
fn from_value(value: Value) -> Result<Self, VmError> {
let future = value.into_future()?;
Ok(future.take()?)
}
}
impl UnsafeFromValue for &Future {
type Output = *const Future;
type Guard = RawOwnedRef;
unsafe fn unsafe_from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
let future = value.into_future()?;
let (future, guard) = OwnedRef::into_raw(future.owned_ref()?);
Ok((future, guard))
}
unsafe fn to_arg(output: Self::Output) -> Self {
&*output
}
}
impl UnsafeFromValue for &mut Future {
type Output = *mut Future;
type Guard = RawOwnedMut;
unsafe fn unsafe_from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
let future = value.into_future()?;
Ok(OwnedMut::into_raw(future.owned_mut()?))
}
unsafe fn to_arg(output: Self::Output) -> Self {
&mut *output
}
}