wasm_bridge_js/conversions/
into_closure.rs1use std::rc::Rc;
2
3use wasm_bindgen::{
4 convert::{FromWasmAbi, ReturnWasmAbi},
5 prelude::Closure,
6 JsValue,
7};
8
9use crate::*;
10
11pub(crate) type MakeClosure<T> = Box<dyn Fn(DataHandle<T>) -> (JsValue, DropHandle)>;
12
13pub trait IntoMakeClosure<T, Params, Results> {
14 fn into_make_closure(self) -> MakeClosure<T>;
15}
16
17impl<T, R, F> IntoMakeClosure<T, (), R> for F
18where
19 T: 'static,
20 F: Fn(Caller<T>) -> R + 'static,
21 R: ToJsValue + 'static,
22 Result<R::ReturnAbi, JsValue>: ReturnWasmAbi, {
24 fn into_make_closure(self) -> MakeClosure<T> {
25 let self_rc = Rc::new(self);
26
27 let make_closure = move |handle: DataHandle<T>| {
28 let caller = Caller::new(handle);
29 let self_clone = self_rc.clone();
30
31 let closure = Closure::<dyn Fn() -> Result<R::ReturnAbi, JsValue>>::new(move || {
32 self_clone(caller.clone()).into_return_abi()
33 });
34
35 DropHandle::from_closure(closure)
36 };
37
38 Box::new(make_closure)
39 }
40}
41
42macro_rules! into_make_closure_single {
43 ($ty:ty) => {
44 impl<T, R, F> IntoMakeClosure<T, $ty, R> for F
45 where
46 T: 'static,
47 F: Fn(Caller<T>, $ty) -> R + 'static,
48 R: ToJsValue + 'static,
49 Result<R::ReturnAbi, JsValue>: ReturnWasmAbi, {
51 fn into_make_closure(self) -> MakeClosure<T> {
52 let self_rc = Rc::new(self);
53
54 let make_closure = move |handle: DataHandle<T>| {
55 let caller = Caller::new(handle);
56 let self_clone = self_rc.clone();
57
58 let closure = Closure::<dyn Fn($ty) -> Result<R::ReturnAbi, JsValue>>::new(
59 move |arg: $ty| self_clone(caller.clone(), arg).into_return_abi(),
60 );
61
62 DropHandle::from_closure(closure)
63 };
64
65 Box::new(make_closure)
66 }
67 }
68 };
69}
70
71into_make_closure_single!(i32);
72into_make_closure_single!(i64);
73into_make_closure_single!(u32);
74into_make_closure_single!(u64);
75into_make_closure_single!(f32);
76into_make_closure_single!(f64);
77
78impl<T, P0, P1, R, F> IntoMakeClosure<T, (P0, P1), R> for F
79where
80 T: 'static,
81 F: Fn(Caller<T>, P0, P1) -> R + 'static,
82 P0: FromWasmAbi + 'static,
83 P1: FromWasmAbi + 'static,
84 R: ToJsValue + 'static,
85 Result<R::ReturnAbi, JsValue>: ReturnWasmAbi, {
87 fn into_make_closure(self) -> MakeClosure<T> {
88 let self_rc = Rc::new(self);
89
90 let make_closure = move |handle: DataHandle<T>| {
91 let caller = Caller::new(handle);
92 let self_clone = self_rc.clone();
93
94 let closure = Closure::<dyn Fn(P0, P1) -> Result<R::ReturnAbi, JsValue>>::new(
95 move |p0: P0, p1: P1| self_clone(caller.clone(), p0, p1).into_return_abi(),
96 );
97
98 DropHandle::from_closure(closure)
99 };
100
101 Box::new(make_closure)
102 }
103}
104
105macro_rules! into_make_closure_many {
106 ($(($param: ident, $name: ident)),*) => {
107 impl<T, $($name, )* R, F> IntoMakeClosure<T, ($($name),*), R> for F
108 where
109 T: 'static,
110 F: Fn(Caller<T>, $($name),*) -> R + 'static,
111 $($name: FromWasmAbi + 'static,)*
112 R: ToJsValue + 'static,
113 Result<R::ReturnAbi, JsValue>: ReturnWasmAbi, {
115 fn into_make_closure(self) -> MakeClosure<T> {
116 let self_rc = Rc::new(self);
117
118 let make_closure = move |handle: DataHandle<T>| {
119 let caller = Caller::new(handle);
120 let self_clone = self_rc.clone();
121
122 let closure =
123 Closure::<dyn Fn($($name),*) -> Result<R::ReturnAbi, JsValue>>::new(move |$($param: $name),*| {
124 self_clone(caller.clone(), $($param),*).into_return_abi()
125 });
126
127 DropHandle::from_closure(closure)
128 };
129
130 Box::new(make_closure)
131 }
132 }
133 };
134}
135
136#[rustfmt::skip]
139into_make_closure_many!((p0, P0), (p1, P1), (p2, P2));
140#[rustfmt::skip]
141into_make_closure_many!((p0, P0), (p1, P1), (p2, P2), (p3, P3));
142#[rustfmt::skip]
143into_make_closure_many!((p0, P0), (p1, P1), (p2, P2), (p3, P3), (p4, P4));
144#[rustfmt::skip]
145into_make_closure_many!((p0, P0), (p1, P1), (p2, P2), (p3, P3), (p4, P4), (p5, P5));
146#[rustfmt::skip]
147into_make_closure_many!((p0, P0), (p1, P1), (p2, P2), (p3, P3), (p4, P4), (p5, P5), (p6, P6));
148#[rustfmt::skip]
149into_make_closure_many!((p0, P0), (p1, P1), (p2, P2), (p3, P3), (p4, P4), (p5, P5), (p6, P6), (p7, P7));
150
151