1use crate::{
2 FromValue, InstallWith, Mut, Named, RawMut, RawRef, RawStr, Ref, Shared, ToValue,
3 UnsafeFromValue, Value, VmError,
4};
5use pin_project::pin_project;
6use std::fmt;
7use std::future;
9use std::pin::Pin;
10use std::task::{Context, Poll};
11
12type DynFuture = dyn future::Future<Output = Result<Value, VmError>> + 'static;
14
15pub struct Future {
18 future: Option<Pin<Box<DynFuture>>>,
19}
20
21impl Future {
22 pub fn new<T, O>(future: T) -> Self
24 where
25 T: 'static + future::Future<Output = Result<O, VmError>>,
26 O: ToValue,
27 {
28 Self {
29 future: Some(Box::pin(async move {
30 let value = future.await?;
31 Ok(value.to_value()?)
32 })),
33 }
34 }
35
36 pub fn is_completed(&self) -> bool {
40 self.future.is_none()
41 }
42}
43
44impl future::Future for Future {
45 type Output = Result<Value, VmError>;
46
47 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<Value, VmError>> {
48 let this = self.get_mut();
49 let mut future = this.future.take().expect("futures can only be polled once");
50
51 match future.as_mut().poll(cx) {
52 Poll::Ready(result) => Poll::Ready(result),
53 Poll::Pending => {
54 this.future = Some(future);
55 Poll::Pending
56 }
57 }
58 }
59}
60
61impl fmt::Debug for Future {
62 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
63 fmt.debug_struct("Future")
64 .field("is_completed", &self.future.is_none())
65 .finish()
66 }
67}
68
69#[pin_project]
71pub struct SelectFuture<T, F> {
72 data: T,
73 #[pin]
74 future: F,
75}
76
77impl<T, F> SelectFuture<T, F> {
78 pub fn new(data: T, future: F) -> Self {
80 Self { data, future }
81 }
82}
83
84impl<T, F> future::Future for SelectFuture<T, F>
85where
86 T: Copy,
87 F: future::Future<Output = Result<Value, VmError>>,
88{
89 type Output = Result<(T, Value), VmError>;
90
91 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
92 let this = self.project();
93 let result = this.future.poll(cx);
94
95 match result {
96 Poll::Ready(result) => match result {
97 Ok(value) => Poll::Ready(Ok((*this.data, value))),
98 Err(e) => Poll::Ready(Err(e)),
99 },
100 Poll::Pending => Poll::Pending,
101 }
102 }
103}
104
105impl FromValue for Shared<Future> {
106 fn from_value(value: Value) -> Result<Self, VmError> {
107 value.into_shared_future()
108 }
109}
110
111impl FromValue for Future {
112 fn from_value(value: Value) -> Result<Self, VmError> {
113 value.into_future()
114 }
115}
116
117impl UnsafeFromValue for &Future {
118 type Output = *const Future;
119 type Guard = RawRef;
120
121 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
122 let future = value.into_shared_future()?;
123 let (future, guard) = Ref::into_raw(future.into_ref()?);
124 Ok((future, guard))
125 }
126
127 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
128 &*output
129 }
130}
131
132impl UnsafeFromValue for &mut Future {
133 type Output = *mut Future;
134 type Guard = RawMut;
135
136 fn from_value(value: Value) -> Result<(Self::Output, Self::Guard), VmError> {
137 let future = value.into_shared_future()?;
138 Ok(Mut::into_raw(future.into_mut()?))
139 }
140
141 unsafe fn unsafe_coerce(output: Self::Output) -> Self {
142 &mut *output
143 }
144}
145
146impl Named for Future {
147 const BASE_NAME: RawStr = RawStr::from_str("Future");
148}
149
150impl InstallWith for Future {}