1use wasm_bindgen::JsValue;
2
3pub trait ToJs {
4 fn to_js(&self) -> JsValue;
5
6 fn to_js_property_value(&self) -> Option<JsValue> {
10 Some(self.to_js())
11 }
12}
13
14impl<T> ToJs for Option<T>
26where
27 T: ToJs,
28{
29 fn to_js(&self) -> JsValue {
30 if let Some(v) = self {
31 v.to_js()
32 } else {
33 JsValue::UNDEFINED
34 }
35 }
36
37 fn to_js_property_value(&self) -> Option<JsValue> {
38 self.as_ref().map(|v| v.to_js())
39 }
40}
41
42impl<'a, B: 'a + ?Sized + ToJs + ToOwned> ToJs for std::borrow::Cow<'a, B> {
43 fn to_js(&self) -> JsValue {
44 self.as_ref().to_js()
45 }
46}
47
48macro_rules! impl_to_js {
49 (deref_copy: $($n:ty)*) => ($(
50 impl ToJs for $n {
51 #[inline]
52 fn to_js(&self) -> JsValue {
53 JsValue::from(*self)
54 }
55 }
56 )*);
57 (into: $($n:ty)*) => ($(
58 impl ToJs for $n {
59 #[inline]
60 fn to_js(&self) -> JsValue {
61 JsValue::from(self)
62 }
63 }
64 )*);
65}
66
67impl_to_js! {
68 into:
69 str
70 String
71 js_sys::Intl::Collator
72 js_sys::Intl::DateTimeFormat
73 js_sys::Intl::NumberFormat
74 js_sys::Intl::PluralRules
75 js_sys::WebAssembly::CompileError
76 js_sys::WebAssembly::Global
77 js_sys::WebAssembly::Instance
78 js_sys::WebAssembly::LinkError
79 js_sys::WebAssembly::Memory
80 js_sys::WebAssembly::Module
81 js_sys::WebAssembly::RuntimeError
82 js_sys::WebAssembly::Table
83 js_sys::Array
84 js_sys::ArrayBuffer
85 js_sys::AsyncIterator
87 js_sys::BigInt
88 js_sys::BigInt64Array
89 js_sys::BigUint64Array
90 js_sys::Boolean
91 js_sys::DataView
92 js_sys::Date
93 js_sys::Error
94 js_sys::EvalError
95 js_sys::Float32Array
96 js_sys::Float64Array
97 js_sys::Function
98 js_sys::Generator
99 js_sys::Int8Array
100 js_sys::Int16Array
101 js_sys::Int32Array
102 js_sys::Iterator
105 js_sys::IteratorNext
106 js_sys::JsString
107 js_sys::Map
108 js_sys::Number
109 js_sys::Object
110 js_sys::Promise
111 js_sys::Proxy
112 js_sys::RangeError
113 js_sys::ReferenceError
114 js_sys::RegExp
115 js_sys::Set
116 js_sys::SharedArrayBuffer
117 js_sys::Symbol
118 js_sys::SyntaxError
119 js_sys::TypeError
120 js_sys::Uint8Array
121 js_sys::Uint8ClampedArray
122 js_sys::Uint16Array
123 js_sys::Uint32Array
124 js_sys::UriError
125 js_sys::WeakMap
126 js_sys::WeakSet
127}
128
129impl_to_js! {
130 deref_copy:
131 &str
132 i8 u8 i16 u16 i32 u32 f32 f64
134 i64 u64 i128 u128 isize usize
136 bool
137}
138
139impl<T: ToJs> ToJs for &T {
140 fn to_js(&self) -> JsValue {
141 (*self).to_js()
142 }
143}
144
145macro_rules! impl_js_for_iter {
146 ($($t:tt)+) => {
147 $($t)+ {
148 #[inline]
149 fn to_js(&self) -> JsValue {
150 js_sys::Array::from_iter(self.iter().map(|v| v.to_js())).into()
151 }
152 }
153 };
154}
155
156impl_js_for_iter! { impl<T: ToJs> ToJs for Vec<T> }
157impl_js_for_iter! { impl<T: ToJs> ToJs for &[T] }
158impl_js_for_iter! { impl<N: ToJs, const S: usize> ToJs for [N; S] }
159
160macro_rules! impl_js_for_tuple {
161 (@impl $arr_method:ident ( $($t:ident),+ $(,)? )) => {
162 impl<$($t: ToJs),+> ToJs for ($($t),+ ,) {
163 #[inline]
164 fn to_js(&self) -> JsValue {
165 #![allow(non_snake_case)]
166 let ($($t),+ ,) = self;
167 js_sys::Array::$arr_method(
168 $(&$t.to_js()),+
169 ).into()
170 }
171 }
172 };
173 (@impl ( $($t:ident),+ $(,)? )) => {
174 impl<$($t: ToJs),+> ToJs for ($($t),+ ,) {
175 #[inline]
176 fn to_js(&self) -> JsValue {
177 #![allow(non_snake_case)]
178 let ($($t),+ ,) = self;
179 js_sys::Array::from_iter([
180 $($t.to_js()),+
181 ]).into()
182 }
183 }
184 };
185 ( $( $($arr_method:ident)? ( $($t:ident),+ $(,)? ) )* ) => {
186 $(
187 impl_js_for_tuple! { @impl $($arr_method)? ($($t),+ ,) }
188 )*
189 };
190}
191
192impl_js_for_tuple! {
193 of1(T0,)
194 of2(T0,T1)
195 of3(T0,T1,T2)
196 of4(T0,T1,T2,T3)
197 of5(T0,T1,T2,T3,T4)
198 (T0,T1,T2,T3,T4,T5)
199 (T0,T1,T2,T3,T4,T5,T6)
200 (T0,T1,T2,T3,T4,T5,T6,T7)
201 (T0,T1,T2,T3,T4,T5,T6,T7,T8)
202 (T0,T1,T2,T3,T4,T5,T6,T7,T8,T9)
203}
204
205impl<T: ToJs> ToJs for Box<T> {
206 #[inline]
207 fn to_js(&self) -> JsValue {
208 self.as_ref().to_js()
209 }
210}
211
212impl ToJs for () {
213 fn to_js(&self) -> JsValue {
214 JsValue::UNDEFINED
215 }
216}
217
218impl ToJs for JsValue {
219 fn to_js(&self) -> JsValue {
220 self.clone()
221 }
222}
223
224impl<T: ?Sized> ToJs for wasm_bindgen::prelude::Closure<T> {
225 fn to_js(&self) -> JsValue {
232 AsRef::<JsValue>::as_ref(&self).clone()
233 }
234}