Skip to main content

wry_bindgen/
rt.rs

1//! Runtime compatibility hooks used by generated wasm-bindgen-style code.
2
3use crate::{
4    __wry_submit_js_function, JsValue,
5    encode::{BatchableResult, BinaryEncode, EncodeTypeDef},
6};
7
8#[doc(hidden)]
9pub use crate::batch::Runtime;
10#[doc(hidden)]
11pub use crate::encode::TypeTag;
12#[doc(hidden)]
13pub use crate::function_registry::{
14    InlineJsModule, JsClassMemberKind, JsClassMemberSpec, JsExportSpec, JsFunctionSpec,
15    LazyJsFunction,
16};
17#[doc(hidden)]
18pub use crate::js_helpers::js_extract_rust_handle as extract_rust_handle;
19#[doc(hidden)]
20pub use inventory;
21
22#[doc(hidden)]
23pub mod object_store {
24    pub use crate::object_store::{
25        ObjectHandle, create_js_wrapper, drop_object, insert_object, remove_object, with_object,
26        with_object_mut,
27    };
28}
29
30#[repr(transparent)]
31#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
32pub struct WasmWord(pub u32);
33
34pub struct Ref<'b, T: ?Sized + 'b> {
35    pub(crate) inner: core::cell::Ref<'b, T>,
36}
37
38impl<T: ?Sized> core::ops::Deref for Ref<'_, T> {
39    type Target = T;
40
41    fn deref(&self) -> &Self::Target {
42        &self.inner
43    }
44}
45
46impl<T: ?Sized> core::borrow::Borrow<T> for Ref<'_, T> {
47    fn borrow(&self) -> &T {
48        self
49    }
50}
51
52pub struct RefMut<'b, T: ?Sized + 'b> {
53    pub(crate) inner: core::cell::RefMut<'b, T>,
54}
55
56impl<T: ?Sized> core::ops::Deref for RefMut<'_, T> {
57    type Target = T;
58
59    fn deref(&self) -> &Self::Target {
60        &self.inner
61    }
62}
63
64impl<T: ?Sized> core::ops::DerefMut for RefMut<'_, T> {
65    fn deref_mut(&mut self) -> &mut Self::Target {
66        &mut self.inner
67    }
68}
69
70impl<T: ?Sized> core::borrow::Borrow<T> for RefMut<'_, T> {
71    fn borrow(&self) -> &T {
72        self
73    }
74}
75
76impl<T: ?Sized> core::borrow::BorrowMut<T> for RefMut<'_, T> {
77    fn borrow_mut(&mut self) -> &mut T {
78        self
79    }
80}
81
82pub mod marker {
83    /// Marker for types whose generic parameters erase to one stable runtime representation.
84    ///
85    /// # Safety
86    /// Implementors must have the same runtime representation as `Repr`.
87    pub unsafe trait ErasableGeneric {
88        type Repr: 'static;
89    }
90
91    unsafe impl<T: ErasableGeneric> ErasableGeneric for &T {
92        type Repr = &'static T::Repr;
93    }
94
95    unsafe impl<T: ErasableGeneric> ErasableGeneric for &mut T {
96        type Repr = &'static mut T::Repr;
97    }
98
99    /// Marker for owned generic values whose representation matches a concrete target.
100    pub trait ErasableGenericOwn<ConcreteTarget>: ErasableGeneric {}
101
102    impl<T, ConcreteTarget> ErasableGenericOwn<ConcreteTarget> for T
103    where
104        ConcreteTarget: ErasableGeneric,
105        T: ErasableGeneric<Repr = <ConcreteTarget as ErasableGeneric>::Repr>,
106    {
107    }
108
109    /// Marker for borrowed generic values whose representation matches a concrete target.
110    pub trait ErasableGenericBorrow<Target: ?Sized> {}
111
112    impl<'a, T: ?Sized + 'a, ConcreteTarget: ?Sized + 'static> ErasableGenericBorrow<ConcreteTarget>
113        for T
114    where
115        &'static ConcreteTarget: ErasableGeneric,
116        &'a T: ErasableGeneric<Repr = <&'static ConcreteTarget as ErasableGeneric>::Repr>,
117    {
118    }
119
120    /// Marker for mutably borrowed generic values whose representation matches a concrete target.
121    pub trait ErasableGenericBorrowMut<Target: ?Sized> {}
122
123    impl<'a, T: ?Sized + 'a, ConcreteTarget: ?Sized + 'static>
124        ErasableGenericBorrowMut<ConcreteTarget> for T
125    where
126        &'static mut ConcreteTarget: ErasableGeneric,
127        &'a mut T: ErasableGeneric<Repr = <&'static mut ConcreteTarget as ErasableGeneric>::Repr>,
128    {
129    }
130}
131
132/// Cast between types via the binary protocol.
133///
134/// This is the wry-bindgen equivalent of wasm-bindgen's wbg_cast.
135/// It encodes `value` using From's BinaryEncode, sends to JS as identity,
136/// and decodes the result using To's BinaryDecode.
137#[inline]
138pub fn wbg_cast<From, To>(value: From) -> To
139where
140    From: BinaryEncode + EncodeTypeDef,
141    To: BatchableResult + EncodeTypeDef,
142{
143    let func: LazyJsFunction<fn(From) -> To> = __wry_submit_js_function!("(a0) => a0");
144    func.call(value)
145}
146
147/// Convert a panic value into a JsValue error.
148///
149/// This is used by wasm-bindgen-futures to convert Rust panics into JS errors.
150#[cfg(feature = "std")]
151pub fn panic_to_panic_error(val: std::boxed::Box<dyn std::any::Any + Send>) -> JsValue {
152    let maybe_panic_msg: Option<&str> = if let Some(s) = val.downcast_ref::<&str>() {
153        Some(s)
154    } else if let Some(s) = val.downcast_ref::<std::string::String>() {
155        Some(s)
156    } else {
157        None
158    };
159    // Create an Error object with the panic message
160    JsValue::from_str(maybe_panic_msg.unwrap_or("Rust panic"))
161}