runtime/
promise.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;
8
9use ion::conversions::{BoxedIntoValue, IntoValue};
10use ion::{Context, Promise};
11use tokio::task::spawn_local;
12
13use crate::ContextExt as _;
14
15/// Returns None if no future queue has been initialised.
16pub fn future_to_promise<'cx, F, Fut, O, E>(cx: &'cx Context, func: F) -> Option<Promise<'cx>>
17where
18	F: FnOnce(Context) -> Fut + 'static,
19	Fut: Future<Output = Result<O, E>> + 'static,
20	O: for<'cx2> IntoValue<'cx2> + 'static,
21	E: for<'cx2> IntoValue<'cx2> + 'static,
22{
23	let promise = Promise::new(cx);
24	let object = promise.handle().get();
25
26	let cx2 = unsafe { Context::new_unchecked(cx.as_ptr()) };
27
28	let handle = spawn_local(async move {
29		let future = func(cx2);
30		let result: Result<BoxedIntoValue, BoxedIntoValue> = match future.await {
31			Ok(o) => Ok(Box::new(o)),
32			Err(e) => Err(Box::new(e)),
33		};
34		(result, object)
35	});
36
37	let event_loop = unsafe { &cx.get_private().event_loop };
38	event_loop.futures.as_ref().map(|futures| {
39		futures.enqueue(handle);
40		promise
41	})
42}