1use std::future::Future;
8use std::pin::Pin;
9use std::task;
10use std::task::Poll;
11
12use futures_channel::mpsc;
13use futures_channel::mpsc::Receiver;
14use futures_util::Stream as _;
15use mozjs::jsval::JSVal;
16
17use crate::{Context, Promise, Value};
18
19pub struct PromiseFuture(Receiver<Result<JSVal, JSVal>>);
20
21impl PromiseFuture {
22 pub fn new(cx: &Context, promise: &Promise) -> PromiseFuture {
23 let (rx, tx) = mpsc::channel(1);
24
25 let mut rx1 = rx;
26 let mut rx2 = rx1.clone();
27
28 promise.add_reactions(
29 cx,
30 move |_, value| {
31 let _ = rx1.try_send(Ok(value.get()));
32 Ok(Value::undefined_handle())
33 },
34 move |_, value| {
35 let _ = rx2.try_send(Err(value.get()));
36 Ok(Value::undefined_handle())
37 },
38 );
39
40 PromiseFuture(tx)
41 }
42}
43
44impl Future for PromiseFuture {
45 type Output = Result<JSVal, JSVal>;
46
47 fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Result<JSVal, JSVal>> {
48 let result = Pin::new(&mut self.0);
49 if let Poll::Ready(Some(val)) = result.poll_next(cx) {
50 Poll::Ready(val)
51 } else {
52 Poll::Pending
53 }
54 }
55}