1use core::marker::PhantomData;
4
5use wry_bindgen_runtime::wire::{BinaryEncode, EncodeTypeDef, EncodedData, ObjectHandle, TypeDef};
6
7#[derive(Clone, Copy)]
8enum CallbackPolicy {
9 RustOwned = 0,
10 JsOwned = 1,
11 JsOwnedOnce = 2,
12}
13
14pub struct CallbackKey<F: ?Sized>(ObjectHandle, CallbackPolicy, PhantomData<F>);
15
16impl<F: ?Sized> CallbackKey<F> {
17 pub fn new(handle: ObjectHandle) -> Self {
18 Self::js_owned(handle)
19 }
20
21 pub fn rust_owned(handle: ObjectHandle) -> Self {
22 CallbackKey(handle, CallbackPolicy::RustOwned, PhantomData)
23 }
24
25 fn js_owned(handle: ObjectHandle) -> Self {
26 CallbackKey(handle, CallbackPolicy::JsOwned, PhantomData)
27 }
28
29 pub fn js_owned_once(handle: ObjectHandle) -> Self {
30 CallbackKey(handle, CallbackPolicy::JsOwnedOnce, PhantomData)
31 }
32}
33
34impl<F: ?Sized> BinaryEncode for CallbackKey<F> {
35 fn encode(self, encoder: &mut EncodedData) {
36 self.0.encode(encoder);
37 (self.1 as u32).encode(encoder);
38 }
39}
40
41macro_rules! callback_type_def_body {
42 ($encoder:expr; R = $R:ty; $($arg:ty),*) => {{
43 $encoder.callback::<fn($($arg),*) -> $R>();
44 }};
45 ($encoder:expr; R = $R:ty; borrow_first; $($rest:ty),*) => {{
46 let count: u8 = 1 $(+ {
47 let _ = PhantomData::<$rest>;
48 1
49 })*;
50 $encoder.callback_with_signature(count, |type_def| {
51 type_def.borrowed_ref();
52 $(<$rest as EncodeTypeDef>::encode_type_def(type_def);)*
53 <$R as EncodeTypeDef>::encode_type_def(type_def);
54 });
55 }};
56}
57
58macro_rules! impl_callback_key_type_def {
59 ($($arg:ident),*) => {
60 impl<R, $($arg,)*> EncodeTypeDef for CallbackKey<fn($($arg),*) -> R>
61 where
62 $($arg: EncodeTypeDef + 'static,)*
63 R: EncodeTypeDef + 'static,
64 {
65 fn encode_type_def(encoder: &mut TypeDef) {
66 callback_type_def_body!(encoder; R = R; $($arg),*);
67 }
68 }
69 };
70}
71
72macro_rules! impl_borrowed_first_callback_key_type_def {
73 ($first:ident $(, $rest:ident)*) => {
74 #[allow(coherence_leak_check)]
75 impl<R, $first, $($rest,)*> EncodeTypeDef for CallbackKey<fn(&$first, $($rest),*) -> R>
76 where
77 $first: EncodeTypeDef + 'static,
78 $($rest: EncodeTypeDef + 'static,)*
79 R: EncodeTypeDef + 'static,
80 {
81 fn encode_type_def(encoder: &mut TypeDef) {
82 callback_type_def_body!(encoder; R = R; borrow_first; $($rest),*);
83 }
84 }
85 };
86}
87
88impl_callback_key_type_def!();
89impl_callback_key_type_def!(A1);
90impl_callback_key_type_def!(A1, A2);
91impl_callback_key_type_def!(A1, A2, A3);
92impl_callback_key_type_def!(A1, A2, A3, A4);
93impl_callback_key_type_def!(A1, A2, A3, A4, A5);
94impl_callback_key_type_def!(A1, A2, A3, A4, A5, A6);
95impl_callback_key_type_def!(A1, A2, A3, A4, A5, A6, A7);
96impl_callback_key_type_def!(A1, A2, A3, A4, A5, A6, A7, A8);
97
98impl_borrowed_first_callback_key_type_def!(A1);
99impl_borrowed_first_callback_key_type_def!(A1, A2);
100impl_borrowed_first_callback_key_type_def!(A1, A2, A3);
101impl_borrowed_first_callback_key_type_def!(A1, A2, A3, A4);
102impl_borrowed_first_callback_key_type_def!(A1, A2, A3, A4, A5);
103impl_borrowed_first_callback_key_type_def!(A1, A2, A3, A4, A5, A6);
104impl_borrowed_first_callback_key_type_def!(A1, A2, A3, A4, A5, A6, A7);
105impl_borrowed_first_callback_key_type_def!(A1, A2, A3, A4, A5, A6, A7, A8);