ion/
future.rs

1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 */
6
7use 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}