1 //! This is an internal module, no stability guarantees are provided. Use at
2 //! your own risk.
3 
4 #![doc(hidden)]
5 
6 use crate::{Clamped, JsValue};
7 use cfg_if::cfg_if;
8 
9 macro_rules! tys {
10     ($($a:ident)*) => (tys! { @ ($($a)*) 0 });
11     (@ () $v:expr) => {};
12     (@ ($a:ident $($b:ident)*) $v:expr) => {
13         pub const $a: u32 = $v;
14         tys!(@ ($($b)*) $v+1);
15     }
16 }
17 
18 // NB: this list must be kept in sync with `crates/cli-support/src/descriptor.rs`
19 tys! {
20     I8
21     U8
22     I16
23     U16
24     I32
25     U32
26     I64
27     U64
28     F32
29     F64
30     BOOLEAN
31     FUNCTION
32     CLOSURE
33     CACHED_STRING
34     STRING
35     REF
36     REFMUT
37     SLICE
38     VECTOR
39     EXTERNREF
40     NAMED_EXTERNREF
41     ENUM
42     RUST_STRUCT
43     CHAR
44     OPTIONAL
45     UNIT
46     CLAMPED
47 }
48 
49 #[inline(always)] // see `interpret.rs` in the the cli-support crate
inform(a: u32)50 pub fn inform(a: u32) {
51     unsafe { super::__wbindgen_describe(a) }
52 }
53 
54 pub trait WasmDescribe {
describe()55     fn describe();
56 }
57 
58 macro_rules! simple {
59     ($($t:ident => $d:ident)*) => ($(
60         impl WasmDescribe for $t {
61             fn describe() { inform($d) }
62         }
63     )*)
64 }
65 
66 simple! {
67     i8 => I8
68     u8 => U8
69     i16 => I16
70     u16 => U16
71     i32 => I32
72     u32 => U32
73     i64 => I64
74     u64 => U64
75     isize => I32
76     usize => U32
77     f32 => F32
78     f64 => F64
79     bool => BOOLEAN
80     char => CHAR
81     JsValue => EXTERNREF
82 }
83 
84 cfg_if! {
85     if #[cfg(feature = "enable-interning")] {
86         simple! {
87             str => CACHED_STRING
88         }
89 
90     } else {
91         simple! {
92             str => STRING
93         }
94     }
95 }
96 
97 impl<T> WasmDescribe for *const T {
describe()98     fn describe() {
99         inform(I32)
100     }
101 }
102 
103 impl<T> WasmDescribe for *mut T {
describe()104     fn describe() {
105         inform(I32)
106     }
107 }
108 
109 impl<T: WasmDescribe> WasmDescribe for [T] {
describe()110     fn describe() {
111         inform(SLICE);
112         T::describe();
113     }
114 }
115 
116 impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a T {
describe()117     fn describe() {
118         inform(REF);
119         T::describe();
120     }
121 }
122 
123 impl<'a, T: WasmDescribe + ?Sized> WasmDescribe for &'a mut T {
describe()124     fn describe() {
125         inform(REFMUT);
126         T::describe();
127     }
128 }
129 
130 if_std! {
131     use std::prelude::v1::*;
132 
133     cfg_if! {
134         if #[cfg(feature = "enable-interning")] {
135             simple! {
136                 String => CACHED_STRING
137             }
138 
139         } else {
140             simple! {
141                 String => STRING
142             }
143         }
144     }
145 
146     impl<T: WasmDescribe> WasmDescribe for Box<[T]> {
147         fn describe() {
148             inform(VECTOR);
149             T::describe();
150         }
151     }
152 
153     impl<T> WasmDescribe for Vec<T> where Box<[T]>: WasmDescribe {
154         fn describe() {
155             <Box<[T]>>::describe();
156         }
157     }
158 }
159 
160 impl<T: WasmDescribe> WasmDescribe for Option<T> {
describe()161     fn describe() {
162         inform(OPTIONAL);
163         T::describe();
164     }
165 }
166 
167 impl WasmDescribe for () {
describe()168     fn describe() {
169         inform(UNIT)
170     }
171 }
172 
173 // Note that this is only for `ReturnWasmAbi for Result<T, JsValue>`, which
174 // throws the result, so we only need to inform about the `T`.
175 impl<T: WasmDescribe> WasmDescribe for Result<T, JsValue> {
describe()176     fn describe() {
177         T::describe()
178     }
179 }
180 
181 impl<T: WasmDescribe> WasmDescribe for Clamped<T> {
describe()182     fn describe() {
183         inform(CLAMPED);
184         T::describe();
185     }
186 }
187