1use js::context::JSContext;
6use script_bindings::reflector::DomObject;
7pub(crate) use script_bindings::routed_promise::RoutedPromiseListener;
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10use servo_base::generic_channel::GenericCallback;
11
12use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
13use crate::dom::promise::RootedPromise;
14use crate::tasks::task_source::TaskSource;
15
16pub(crate) struct RoutedPromiseContext<
17 R: Serialize + DeserializeOwned + Send,
18 T: RoutedPromiseListener<crate::DomTypeHolder, R> + DomObject,
19> {
20 trusted: TrustedPromise,
21 receiver: Trusted<T>,
22 _phantom: std::marker::PhantomData<R>,
23}
24
25impl<
26 R: Serialize + DeserializeOwned + Send,
27 T: RoutedPromiseListener<crate::DomTypeHolder, R> + DomObject,
28> RoutedPromiseContext<R, T>
29{
30 fn response(self, cx: &mut JSContext, response: R) {
31 let promise = self.trusted.root(cx);
32 self.receiver.root().handle_response(cx, response, &promise);
33 }
34}
35
36pub(crate) fn callback_promise<
37 R: Serialize + DeserializeOwned + Send + 'static,
38 T: RoutedPromiseListener<crate::DomTypeHolder, R> + DomObject + 'static,
39>(
40 promise: &RootedPromise,
41 receiver: &T,
42 task_source: TaskSource,
43) -> GenericCallback<R> {
44 let task_source = task_source.to_sendable();
45 let mut trusted: Option<TrustedPromise> = Some(TrustedPromise::from(promise));
46 let trusted_receiver = Trusted::new(receiver);
47 GenericCallback::new(move |message| {
48 let trusted = if let Some(trusted) = trusted.take() {
49 trusted
50 } else {
51 error!("RoutedPromiseListener callback called twice!");
52 return;
53 };
54
55 let context = RoutedPromiseContext {
56 trusted,
57 receiver: trusted_receiver.clone(),
58 _phantom: Default::default(),
59 };
60 task_source.queue(task!(routed_promise_task: move|cx| {
61 context.response(cx, message.unwrap());
62 }));
63 })
64 .expect("Could not create callback in script.")
65}