wasm_bindgen/
describe.rs

1//! This is an internal module, no stability guarantees are provided. Use at
2//! your own risk.
3
4#![doc(hidden)]
5
6use alloc::boxed::Box;
7use alloc::string::String;
8use alloc::vec::Vec;
9use core::{mem::MaybeUninit, ptr::NonNull};
10
11use crate::{Clamped, JsError, JsObject, JsValue};
12use cfg_if::cfg_if;
13
14macro_rules! tys {
15    ($($a:ident)*) => (tys! { @ ($($a)*) 0 });
16    (@ () $v:expr) => {};
17    (@ ($a:ident $($b:ident)*) $v:expr) => {
18        pub const $a: u32 = $v;
19        tys!(@ ($($b)*) $v+1);
20    }
21}
22
23// NB: this list must be kept in sync with `crates/cli-support/src/descriptor.rs`
24tys! {
25    I8
26    U8
27    I16
28    U16
29    I32
30    U32
31    I64
32    U64
33    I128
34    U128
35    F32
36    F64
37    BOOLEAN
38    FUNCTION
39    CLOSURE
40    CACHED_STRING
41    STRING
42    REF
43    REFMUT
44    LONGREF
45    SLICE
46    VECTOR
47    EXTERNREF
48    NAMED_EXTERNREF
49    ENUM
50    STRING_ENUM
51    RUST_STRUCT
52    CHAR
53    OPTIONAL
54    RESULT
55    UNIT
56    CLAMPED
57    NONNULL
58}
59
60#[inline(always)] // see the wasm-interpreter crate
61#[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
62pub fn inform(a: u32) {
63    unsafe { super::__wbindgen_describe(a) }
64}
65
66pub trait WasmDescribe {
67    fn describe();
68}
69
70/// Trait for element types to implement WasmDescribe for vectors of
71/// themselves.
72pub trait WasmDescribeVector {
73    fn describe_vector();
74}
75
76macro_rules! simple {
77    ($($t:ident => $d:ident)*) => ($(
78        impl WasmDescribe for $t {
79            #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
80            fn describe() { inform($d) }
81        }
82    )*)
83}
84
85simple! {
86    i8 => I8
87    u8 => U8
88    i16 => I16
89    u16 => U16
90    i32 => I32
91    u32 => U32
92    i64 => I64
93    u64 => U64
94    i128 => I128
95    u128 => U128
96    isize => I32
97    usize => U32
98    f32 => F32
99    f64 => F64
100    bool => BOOLEAN
101    char => CHAR
102    JsValue => EXTERNREF
103}
104
105cfg_if! {
106    if #[cfg(feature = "enable-interning")] {
107        simple! {
108            str => CACHED_STRING
109        }
110
111    } else {
112        simple! {
113            str => STRING
114        }
115    }
116}
117
118impl<T> WasmDescribe for *const T {
119    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
120    fn describe() {
121        inform(U32)
122    }
123}
124
125impl<T> WasmDescribe for *mut T {
126    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
127    fn describe() {
128        inform(U32)
129    }
130}
131
132impl<T> WasmDescribe for NonNull<T> {
133    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
134    fn describe() {
135        inform(NONNULL)
136    }
137}
138
139impl<T: WasmDescribe> WasmDescribe for [T] {
140    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
141    fn describe() {
142        inform(SLICE);
143        T::describe();
144    }
145}
146
147impl<T: WasmDescribe + ?Sized> WasmDescribe for &T {
148    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
149    fn describe() {
150        inform(REF);
151        T::describe();
152    }
153}
154
155impl<T: WasmDescribe + ?Sized> WasmDescribe for &mut T {
156    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
157    fn describe() {
158        inform(REFMUT);
159        T::describe();
160    }
161}
162
163cfg_if! {
164    if #[cfg(feature = "enable-interning")] {
165        simple! {
166            String => CACHED_STRING
167        }
168
169    } else {
170        simple! {
171            String => STRING
172        }
173    }
174}
175
176impl WasmDescribeVector for JsValue {
177    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
178    fn describe_vector() {
179        inform(VECTOR);
180        JsValue::describe();
181    }
182}
183
184impl<T: JsObject> WasmDescribeVector for T {
185    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
186    fn describe_vector() {
187        inform(VECTOR);
188        T::describe();
189    }
190}
191
192impl<T: WasmDescribeVector> WasmDescribe for Box<[T]> {
193    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
194    fn describe() {
195        T::describe_vector();
196    }
197}
198
199impl<T> WasmDescribe for Vec<T>
200where
201    Box<[T]>: WasmDescribe,
202{
203    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
204    fn describe() {
205        <Box<[T]>>::describe();
206    }
207}
208
209impl<T: WasmDescribe> WasmDescribe for Option<T> {
210    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
211    fn describe() {
212        inform(OPTIONAL);
213        T::describe();
214    }
215}
216
217impl WasmDescribe for () {
218    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
219    fn describe() {
220        inform(UNIT)
221    }
222}
223
224impl<T: WasmDescribe, E: Into<JsValue>> WasmDescribe for Result<T, E> {
225    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
226    fn describe() {
227        inform(RESULT);
228        T::describe();
229    }
230}
231
232impl<T: WasmDescribe> WasmDescribe for MaybeUninit<T> {
233    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
234    fn describe() {
235        T::describe();
236    }
237}
238
239impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
240    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
241    fn describe() {
242        inform(CLAMPED);
243        T::describe();
244    }
245}
246
247impl WasmDescribe for JsError {
248    #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))]
249    fn describe() {
250        JsValue::describe();
251    }
252}