1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::char;
4use core::mem::{self, ManuallyDrop};
5use core::ptr::NonNull;
6
7use crate::__rt::marker::ErasableGeneric;
8use crate::__rt::{WasmSignedWordRepr, WasmWordRepr};
9use crate::convert::traits::{WasmAbi, WasmPrimitive};
10use crate::convert::{
11 FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, OptionFromWasmAbi, OptionIntoWasmAbi,
12 RefFromWasmAbi, ReturnWasmAbi, TryFromJsValue, UpcastFrom,
13};
14use crate::sys::Promising;
15use crate::sys::{JsNullable, JsOption, Undefined};
16use crate::{Clamped, JsError, JsValue, UnwrapThrowExt};
17
18impl<T: WasmPrimitive> WasmAbi for T {
20 type Prim1 = Self;
21 type Prim2 = ();
22 type Prim3 = ();
23 type Prim4 = ();
24
25 #[inline]
26 fn split(self) -> (Self, (), (), ()) {
27 (self, (), (), ())
28 }
29
30 #[inline]
31 fn join(prim: Self, _: (), _: (), _: ()) -> Self {
32 prim
33 }
34}
35
36impl WasmAbi for i128 {
37 type Prim1 = u64;
38 type Prim2 = u64;
39 type Prim3 = ();
40 type Prim4 = ();
41
42 #[inline]
43 fn split(self) -> (u64, u64, (), ()) {
44 let low = self as u64;
45 let high = (self >> 64) as u64;
46 (low, high, (), ())
47 }
48
49 #[inline]
50 fn join(low: u64, high: u64, _: (), _: ()) -> Self {
51 (((high as u128) << 64) | low as u128) as i128
52 }
53}
54impl WasmAbi for u128 {
55 type Prim1 = u64;
56 type Prim2 = u64;
57 type Prim3 = ();
58 type Prim4 = ();
59
60 #[inline]
61 fn split(self) -> (u64, u64, (), ()) {
62 let low = self as u64;
63 let high = (self >> 64) as u64;
64 (low, high, (), ())
65 }
66
67 #[inline]
68 fn join(low: u64, high: u64, _: (), _: ()) -> Self {
69 ((high as u128) << 64) | low as u128
70 }
71}
72
73impl<T: WasmAbi<Prim4 = ()>> WasmAbi for Option<T> {
74 type Prim1 = u32;
76 type Prim2 = T::Prim1;
77 type Prim3 = T::Prim2;
78 type Prim4 = T::Prim3;
79
80 #[inline]
81 fn split(self) -> (u32, T::Prim1, T::Prim2, T::Prim3) {
82 match self {
83 None => (
84 0,
85 Default::default(),
86 Default::default(),
87 Default::default(),
88 ),
89 Some(value) => {
90 let (prim1, prim2, prim3, ()) = value.split();
91 (1, prim1, prim2, prim3)
92 }
93 }
94 }
95
96 #[inline]
97 fn join(is_some: u32, prim1: T::Prim1, prim2: T::Prim2, prim3: T::Prim3) -> Self {
98 if is_some == 0 {
99 None
100 } else {
101 Some(T::join(prim1, prim2, prim3, ()))
102 }
103 }
104}
105
106macro_rules! type_wasm_native {
107 ($($t:tt as $c:tt)*) => ($(
108 impl IntoWasmAbi for $t {
109 type Abi = $c;
110
111 #[inline]
112 fn into_abi(self) -> $c { self as $c }
113 }
114
115 impl FromWasmAbi for $t {
116 type Abi = $c;
117
118 #[inline]
119 unsafe fn from_abi(js: $c) -> Self { js as $t }
120 }
121
122 impl IntoWasmAbi for Option<$t> {
123 type Abi = Option<$c>;
124
125 #[inline]
126 fn into_abi(self) -> Self::Abi {
127 self.map(|v| v as $c)
128 }
129 }
130
131 impl FromWasmAbi for Option<$t> {
132 type Abi = Option<$c>;
133
134 #[inline]
135 unsafe fn from_abi(js: Self::Abi) -> Self {
136 js.map(|v: $c| v as $t)
137 }
138 }
139
140 impl UpcastFrom<$t> for JsValue {}
141 impl UpcastFrom<$t> for JsOption<JsValue> {}
142 impl UpcastFrom<$t> for JsNullable<JsValue> {}
143 impl UpcastFrom<$t> for $t {}
144 )*)
145}
146
147type_wasm_native!(
148 i64 as i64
149 u64 as u64
150 i128 as i128
151 u128 as u128
152 f64 as f64
153);
154
155impl UpcastFrom<u64> for u128 {}
156impl UpcastFrom<u64> for JsOption<u128> {}
157impl UpcastFrom<u64> for JsNullable<u128> {}
158impl UpcastFrom<i64> for i128 {}
159impl UpcastFrom<i64> for JsOption<i128> {}
160impl UpcastFrom<i64> for JsNullable<i128> {}
161
162const F64_ABI_OPTION_SENTINEL: f64 = 9007199254740991_f64;
172
173macro_rules! type_wasm_native_f64_option {
174 ($($t:tt as $c:tt)*) => ($(
175 impl IntoWasmAbi for $t {
176 type Abi = $c;
177
178 #[inline]
179 fn into_abi(self) -> $c { self as $c }
180 }
181
182 impl FromWasmAbi for $t {
183 type Abi = $c;
184
185 #[inline]
186 unsafe fn from_abi(js: $c) -> Self { js as $t }
187 }
188
189 unsafe impl ErasableGeneric for $t {
190 type Repr = $t;
191 }
192
193 impl Promising for $t {
194 type Resolution = $t;
195 }
196
197 impl IntoWasmAbi for Option<$t> {
198 type Abi = f64;
199
200 #[inline]
201 fn into_abi(self) -> Self::Abi {
202 self.map(|v| v as $c as f64).unwrap_or(F64_ABI_OPTION_SENTINEL)
203 }
204 }
205
206 impl FromWasmAbi for Option<$t> {
207 type Abi = f64;
208
209 #[inline]
210 unsafe fn from_abi(js: Self::Abi) -> Self {
211 if js == F64_ABI_OPTION_SENTINEL {
212 None
213 } else {
214 Some(js as $c as $t)
215 }
216 }
217 }
218
219 impl UpcastFrom<$t> for JsValue {}
220 impl UpcastFrom<$t> for JsOption<JsValue> {}
221 impl UpcastFrom<$t> for JsNullable<JsValue> {}
222 impl UpcastFrom<$t> for $t {}
223 )*)
224}
225
226type_wasm_native_f64_option!(
227 i32 as i32
228 u32 as u32
229 f32 as f32
230 isize as WasmSignedWordRepr
231 usize as WasmWordRepr
232);
233
234#[cfg(target_pointer_width = "32")]
235impl UpcastFrom<isize> for i32 {}
236#[cfg(target_pointer_width = "32")]
237impl UpcastFrom<isize> for JsOption<i32> {}
238#[cfg(target_pointer_width = "32")]
239impl UpcastFrom<isize> for JsNullable<i32> {}
240
241impl UpcastFrom<isize> for i64 {}
242impl UpcastFrom<isize> for JsOption<i64> {}
243impl UpcastFrom<isize> for JsNullable<i64> {}
244impl UpcastFrom<isize> for i128 {}
245impl UpcastFrom<isize> for JsOption<i128> {}
246impl UpcastFrom<isize> for JsNullable<i128> {}
247
248impl UpcastFrom<i32> for isize {}
249impl UpcastFrom<i32> for JsOption<isize> {}
250impl UpcastFrom<i32> for JsNullable<isize> {}
251impl UpcastFrom<i32> for i64 {}
252impl UpcastFrom<i32> for JsOption<i64> {}
253impl UpcastFrom<i32> for JsNullable<i64> {}
254impl UpcastFrom<i32> for i128 {}
255impl UpcastFrom<i32> for JsOption<i128> {}
256impl UpcastFrom<i32> for JsNullable<i128> {}
257
258impl UpcastFrom<u32> for usize {}
259impl UpcastFrom<u32> for JsOption<usize> {}
260impl UpcastFrom<u32> for JsNullable<usize> {}
261impl UpcastFrom<u32> for u64 {}
262impl UpcastFrom<u32> for JsOption<u64> {}
263impl UpcastFrom<u32> for JsNullable<u64> {}
264impl UpcastFrom<u32> for u128 {}
265impl UpcastFrom<u32> for JsOption<u128> {}
266impl UpcastFrom<u32> for JsNullable<u128> {}
267
268#[cfg(target_pointer_width = "32")]
269impl UpcastFrom<usize> for u32 {}
270#[cfg(target_pointer_width = "32")]
271impl UpcastFrom<usize> for JsOption<u32> {}
272#[cfg(target_pointer_width = "32")]
273impl UpcastFrom<usize> for JsNullable<u32> {}
274impl UpcastFrom<usize> for u64 {}
275impl UpcastFrom<usize> for JsOption<u64> {}
276impl UpcastFrom<usize> for JsNullable<u64> {}
277impl UpcastFrom<usize> for u128 {}
278impl UpcastFrom<usize> for JsOption<u128> {}
279impl UpcastFrom<usize> for JsNullable<u128> {}
280
281impl UpcastFrom<f32> for f64 {}
282impl UpcastFrom<f32> for JsOption<f64> {}
283impl UpcastFrom<f32> for JsNullable<f64> {}
284
285const U32_ABI_OPTION_SENTINEL: u32 = 0x00FF_FFFFu32;
291
292macro_rules! type_abi_as_u32 {
293 ($($t:tt)*) => ($(
294 impl IntoWasmAbi for $t {
295 type Abi = u32;
296
297 #[inline]
298 fn into_abi(self) -> u32 { self as u32 }
299 }
300
301 impl FromWasmAbi for $t {
302 type Abi = u32;
303
304 #[inline]
305 unsafe fn from_abi(js: u32) -> Self { js as $t }
306 }
307
308 impl OptionIntoWasmAbi for $t {
309 #[inline]
310 fn none() -> u32 { U32_ABI_OPTION_SENTINEL }
311 }
312
313 impl OptionFromWasmAbi for $t {
314 #[inline]
315 fn is_none(js: &u32) -> bool { *js == U32_ABI_OPTION_SENTINEL }
316 }
317
318 unsafe impl ErasableGeneric for $t {
319 type Repr = $t;
320 }
321
322 impl Promising for $t {
323 type Resolution = $t;
324 }
325
326 impl UpcastFrom<$t> for JsValue {}
327 impl UpcastFrom<$t> for JsOption<JsValue> {}
328 impl UpcastFrom<$t> for JsNullable<JsValue> {}
329 impl UpcastFrom<$t> for $t {}
330 )*)
331}
332
333type_abi_as_u32!(i8 u8 i16 u16);
334
335impl UpcastFrom<i8> for i16 {}
336impl UpcastFrom<i8> for JsOption<i16> {}
337impl UpcastFrom<i8> for JsNullable<i16> {}
338impl UpcastFrom<i8> for i32 {}
339impl UpcastFrom<i8> for JsOption<i32> {}
340impl UpcastFrom<i8> for JsNullable<i32> {}
341impl UpcastFrom<i8> for i64 {}
342impl UpcastFrom<i8> for JsOption<i64> {}
343impl UpcastFrom<i8> for JsNullable<i64> {}
344impl UpcastFrom<i8> for i128 {}
345impl UpcastFrom<i8> for JsOption<i128> {}
346impl UpcastFrom<i8> for JsNullable<i128> {}
347
348impl UpcastFrom<u8> for u16 {}
349impl UpcastFrom<u8> for JsOption<u16> {}
350impl UpcastFrom<u8> for JsNullable<u16> {}
351impl UpcastFrom<u8> for u32 {}
352impl UpcastFrom<u8> for JsOption<u32> {}
353impl UpcastFrom<u8> for JsNullable<u32> {}
354impl UpcastFrom<u8> for u64 {}
355impl UpcastFrom<u8> for JsOption<u64> {}
356impl UpcastFrom<u8> for JsNullable<u64> {}
357impl UpcastFrom<u8> for u128 {}
358impl UpcastFrom<u8> for JsOption<u128> {}
359impl UpcastFrom<u8> for JsNullable<u128> {}
360
361impl UpcastFrom<i16> for i32 {}
362impl UpcastFrom<i16> for JsOption<i32> {}
363impl UpcastFrom<i16> for JsNullable<i32> {}
364impl UpcastFrom<i16> for i64 {}
365impl UpcastFrom<i16> for JsOption<i64> {}
366impl UpcastFrom<i16> for JsNullable<i64> {}
367impl UpcastFrom<i16> for i128 {}
368impl UpcastFrom<i16> for JsOption<i128> {}
369impl UpcastFrom<i16> for JsNullable<i128> {}
370
371impl UpcastFrom<u16> for u32 {}
372impl UpcastFrom<u16> for JsOption<u32> {}
373impl UpcastFrom<u16> for JsNullable<u32> {}
374impl UpcastFrom<u16> for u64 {}
375impl UpcastFrom<u16> for JsOption<u64> {}
376impl UpcastFrom<u16> for JsNullable<u64> {}
377impl UpcastFrom<u16> for u128 {}
378impl UpcastFrom<u16> for JsOption<u128> {}
379impl UpcastFrom<u16> for JsNullable<u128> {}
380
381impl IntoWasmAbi for bool {
382 type Abi = u32;
383
384 #[inline]
385 fn into_abi(self) -> u32 {
386 self as u32
387 }
388}
389
390impl FromWasmAbi for bool {
391 type Abi = u32;
392
393 #[inline]
394 unsafe fn from_abi(js: u32) -> bool {
395 js != 0
396 }
397}
398
399impl OptionIntoWasmAbi for bool {
400 #[inline]
401 fn none() -> u32 {
402 U32_ABI_OPTION_SENTINEL
403 }
404}
405
406impl OptionFromWasmAbi for bool {
407 #[inline]
408 fn is_none(js: &u32) -> bool {
409 *js == U32_ABI_OPTION_SENTINEL
410 }
411}
412
413unsafe impl ErasableGeneric for bool {
414 type Repr = bool;
415}
416
417impl Promising for bool {
418 type Resolution = bool;
419}
420
421impl UpcastFrom<bool> for JsValue {}
422impl UpcastFrom<bool> for JsOption<JsValue> {}
423impl UpcastFrom<bool> for JsNullable<JsValue> {}
424impl UpcastFrom<bool> for bool {}
425
426impl IntoWasmAbi for char {
427 type Abi = u32;
428
429 #[inline]
430 fn into_abi(self) -> u32 {
431 self as u32
432 }
433}
434
435impl FromWasmAbi for char {
436 type Abi = u32;
437
438 #[inline]
439 unsafe fn from_abi(js: u32) -> char {
440 char::from_u32_unchecked(js)
442 }
443}
444
445impl OptionIntoWasmAbi for char {
446 #[inline]
447 fn none() -> u32 {
448 U32_ABI_OPTION_SENTINEL
449 }
450}
451
452impl OptionFromWasmAbi for char {
453 #[inline]
454 fn is_none(js: &u32) -> bool {
455 *js == U32_ABI_OPTION_SENTINEL
456 }
457}
458
459unsafe impl ErasableGeneric for char {
460 type Repr = char;
461}
462
463impl Promising for char {
464 type Resolution = char;
465}
466
467impl UpcastFrom<char> for JsValue {}
468impl UpcastFrom<char> for JsOption<JsValue> {}
469impl UpcastFrom<char> for JsNullable<JsValue> {}
470impl UpcastFrom<char> for char {}
471
472impl<T> IntoWasmAbi for *const T {
473 type Abi = WasmWordRepr;
474
475 #[inline]
476 fn into_abi(self) -> Self::Abi {
477 self as usize as WasmWordRepr
478 }
479}
480
481impl<T> FromWasmAbi for *const T {
482 type Abi = WasmWordRepr;
483
484 #[inline]
485 unsafe fn from_abi(js: Self::Abi) -> *const T {
486 js as usize as *const T
487 }
488}
489
490unsafe impl<T: ErasableGeneric> ErasableGeneric for *const T {
491 type Repr = *const T::Repr;
492}
493
494impl<T, Target> UpcastFrom<*const T> for *const Target where Target: UpcastFrom<T> {}
495impl<T, Target> UpcastFrom<*const T> for JsOption<*const Target> where Target: UpcastFrom<T> {}
496impl<T, Target> UpcastFrom<*const T> for JsNullable<*const Target> where Target: UpcastFrom<T> {}
497
498impl<T> IntoWasmAbi for Option<*const T> {
499 type Abi = f64;
500
501 #[inline]
502 fn into_abi(self) -> Self::Abi {
503 self.map(|ptr| ptr as usize as f64)
504 .unwrap_or(F64_ABI_OPTION_SENTINEL)
505 }
506}
507
508unsafe impl<T: ErasableGeneric> ErasableGeneric for Option<T> {
509 type Repr = Option<<T as ErasableGeneric>::Repr>;
510}
511
512impl<T, Target> UpcastFrom<Option<T>> for Option<Target> where Target: UpcastFrom<T> {}
513impl<T, Target> UpcastFrom<Option<T>> for JsOption<Option<Target>> where Target: UpcastFrom<T> {}
514impl<T, Target> UpcastFrom<Option<T>> for JsNullable<Option<Target>> where Target: UpcastFrom<T> {}
515
516impl<T> FromWasmAbi for Option<*const T> {
517 type Abi = f64;
518
519 #[inline]
520 unsafe fn from_abi(js: Self::Abi) -> Option<*const T> {
521 if js == F64_ABI_OPTION_SENTINEL {
522 None
523 } else {
524 Some(js as usize as *const T)
525 }
526 }
527}
528
529impl<T> IntoWasmAbi for *mut T {
530 type Abi = WasmWordRepr;
531
532 #[inline]
533 fn into_abi(self) -> Self::Abi {
534 self as usize as WasmWordRepr
535 }
536}
537
538impl<T> FromWasmAbi for *mut T {
539 type Abi = WasmWordRepr;
540
541 #[inline]
542 unsafe fn from_abi(js: Self::Abi) -> *mut T {
543 js as usize as *mut T
544 }
545}
546
547impl<T> IntoWasmAbi for Option<*mut T> {
548 type Abi = f64;
549
550 #[inline]
551 fn into_abi(self) -> Self::Abi {
552 self.map(|ptr| ptr as usize as f64)
553 .unwrap_or(F64_ABI_OPTION_SENTINEL)
554 }
555}
556
557impl<T> FromWasmAbi for Option<*mut T> {
558 type Abi = f64;
559
560 #[inline]
561 unsafe fn from_abi(js: Self::Abi) -> Option<*mut T> {
562 if js == F64_ABI_OPTION_SENTINEL {
563 None
564 } else {
565 Some(js as usize as *mut T)
566 }
567 }
568}
569
570impl<T> IntoWasmAbi for NonNull<T> {
571 type Abi = WasmWordRepr;
572
573 #[inline]
574 fn into_abi(self) -> Self::Abi {
575 self.as_ptr() as usize as WasmWordRepr
576 }
577}
578
579impl<T> OptionIntoWasmAbi for NonNull<T> {
580 #[inline]
581 fn none() -> Self::Abi {
582 0 as WasmWordRepr
583 }
584}
585
586impl<T> FromWasmAbi for NonNull<T> {
587 type Abi = WasmWordRepr;
588
589 #[inline]
590 unsafe fn from_abi(js: Self::Abi) -> Self {
591 NonNull::new_unchecked(js as usize as *mut T)
593 }
594}
595
596impl<T> OptionFromWasmAbi for NonNull<T> {
597 #[inline]
598 fn is_none(js: &Self::Abi) -> bool {
599 *js == 0 as WasmWordRepr
600 }
601}
602
603impl IntoWasmAbi for JsValue {
604 type Abi = u32;
605
606 #[inline]
607 fn into_abi(self) -> u32 {
608 let ret = self.idx;
609 mem::forget(self);
610 ret
611 }
612}
613
614impl FromWasmAbi for JsValue {
615 type Abi = u32;
616
617 #[inline]
618 unsafe fn from_abi(js: u32) -> JsValue {
619 JsValue::_new(js)
620 }
621}
622
623impl IntoWasmAbi for &JsValue {
624 type Abi = u32;
625
626 #[inline]
627 fn into_abi(self) -> u32 {
628 self.idx
629 }
630}
631
632impl RefFromWasmAbi for JsValue {
633 type Abi = u32;
634 type Anchor = ManuallyDrop<JsValue>;
635
636 #[inline]
637 unsafe fn ref_from_abi(js: u32) -> Self::Anchor {
638 ManuallyDrop::new(JsValue::_new(js))
639 }
640}
641
642impl LongRefFromWasmAbi for JsValue {
643 type Abi = u32;
644 type Anchor = JsValue;
645
646 #[inline]
647 unsafe fn long_ref_from_abi(js: u32) -> Self::Anchor {
648 Self::from_abi(js)
649 }
650}
651
652impl OptionIntoWasmAbi for JsValue {
653 #[inline]
654 fn none() -> u32 {
655 crate::__rt::JSIDX_UNDEFINED
656 }
657}
658
659impl OptionIntoWasmAbi for &JsValue {
660 #[inline]
661 fn none() -> u32 {
662 crate::__rt::JSIDX_UNDEFINED
663 }
664}
665
666impl OptionFromWasmAbi for JsValue {
667 #[inline]
668 fn is_none(js: &u32) -> bool {
669 unsafe { Self::ref_from_abi(*js) }.is_undefined()
670 }
671}
672
673impl<T: OptionIntoWasmAbi> IntoWasmAbi for Option<T> {
674 type Abi = T::Abi;
675
676 #[inline]
677 fn into_abi(self) -> T::Abi {
678 match self {
679 None => T::none(),
680 Some(me) => me.into_abi(),
681 }
682 }
683}
684
685impl<T: OptionFromWasmAbi> FromWasmAbi for Option<T> {
686 type Abi = T::Abi;
687
688 #[inline]
689 unsafe fn from_abi(js: T::Abi) -> Self {
690 if T::is_none(&js) {
691 None
692 } else {
693 Some(T::from_abi(js))
694 }
695 }
696}
697
698impl<T: OptionIntoWasmAbi + ErasableGeneric<Repr = JsValue> + Promising> Promising for Option<T> {
699 type Resolution = Option<<T as Promising>::Resolution>;
700}
701
702impl<T: IntoWasmAbi> IntoWasmAbi for Clamped<T> {
703 type Abi = T::Abi;
704
705 #[inline]
706 fn into_abi(self) -> Self::Abi {
707 self.0.into_abi()
708 }
709}
710
711impl<T: FromWasmAbi> FromWasmAbi for Clamped<T> {
712 type Abi = T::Abi;
713
714 #[inline]
715 unsafe fn from_abi(js: T::Abi) -> Self {
716 Clamped(T::from_abi(js))
717 }
718}
719
720impl IntoWasmAbi for () {
721 type Abi = ();
722
723 #[inline]
724 fn into_abi(self) {
725 self
726 }
727}
728
729impl FromWasmAbi for () {
730 type Abi = ();
731
732 #[inline]
733 unsafe fn from_abi(_js: ()) {}
734}
735
736impl Promising for () {
737 type Resolution = Undefined;
738}
739
740impl UpcastFrom<()> for JsValue {}
741impl UpcastFrom<()> for () {}
742
743unsafe impl ErasableGeneric for () {
744 type Repr = ();
745}
746
747impl<T: WasmAbi<Prim3 = (), Prim4 = ()>> WasmAbi for Result<T, u32> {
748 type Prim1 = T::Prim1;
749 type Prim2 = T::Prim2;
750 type Prim3 = u32;
755 type Prim4 = u32;
757
758 #[inline]
759 fn split(self) -> (T::Prim1, T::Prim2, u32, u32) {
760 match self {
761 Ok(value) => {
762 let (prim1, prim2, (), ()) = value.split();
763 (prim1, prim2, 0, 0)
764 }
765 Err(err) => (Default::default(), Default::default(), err, 1),
766 }
767 }
768
769 #[inline]
770 fn join(prim1: T::Prim1, prim2: T::Prim2, err: u32, is_err: u32) -> Self {
771 if is_err == 0 {
772 Ok(T::join(prim1, prim2, (), ()))
773 } else {
774 Err(err)
775 }
776 }
777}
778
779impl<T, E> ReturnWasmAbi for Result<T, E>
780where
781 T: IntoWasmAbi,
782 E: Into<JsValue>,
783 T::Abi: WasmAbi<Prim3 = (), Prim4 = ()>,
784{
785 type Abi = Result<T::Abi, u32>;
786
787 #[inline]
788 fn return_abi(self) -> Self::Abi {
789 match self {
790 Ok(v) => Ok(v.into_abi()),
791 Err(e) => {
792 let jsval = e.into();
793 Err(jsval.into_abi())
794 }
795 }
796 }
797}
798
799unsafe impl<T: ErasableGeneric, E: ErasableGeneric> ErasableGeneric for Result<T, E> {
800 type Repr = Result<<T as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr>;
801}
802
803impl<T: ErasableGeneric + Promising, E: ErasableGeneric> Promising for Result<T, E> {
804 type Resolution = Result<<T as Promising>::Resolution, E>;
805}
806
807impl<T, E, TargetT, TargetE> UpcastFrom<Result<T, E>> for Result<TargetT, TargetE>
808where
809 TargetT: UpcastFrom<T>,
810 TargetE: UpcastFrom<E>,
811{
812}
813impl<T, E, TargetT, TargetE> UpcastFrom<Result<T, E>> for JsOption<Result<TargetT, TargetE>>
814where
815 TargetT: UpcastFrom<T>,
816 TargetE: UpcastFrom<E>,
817{
818}
819impl<T, E, TargetT, TargetE> UpcastFrom<Result<T, E>> for JsNullable<Result<TargetT, TargetE>>
820where
821 TargetT: UpcastFrom<T>,
822 TargetE: UpcastFrom<E>,
823{
824}
825
826unsafe impl ErasableGeneric for JsError {
827 type Repr = JsValue;
828}
829
830impl IntoWasmAbi for JsError {
831 type Abi = <JsValue as IntoWasmAbi>::Abi;
832
833 fn into_abi(self) -> Self::Abi {
834 self.value.into_abi()
835 }
836}
837
838impl FromWasmAbi for JsError {
840 type Abi = <JsValue as FromWasmAbi>::Abi;
841
842 #[inline]
843 unsafe fn from_abi(js: Self::Abi) -> Self {
844 JsError {
845 value: JsValue::from_abi(js),
846 }
847 }
848}
849
850impl Promising for JsError {
851 type Resolution = JsError;
852}
853
854impl UpcastFrom<JsError> for JsValue {}
855impl UpcastFrom<JsError> for JsOption<JsValue> {}
856impl UpcastFrom<JsError> for JsNullable<JsValue> {}
857impl UpcastFrom<JsError> for JsError {}
858
859pub fn js_value_vector_into_abi<T: Into<JsValue>>(
867 vector: Box<[T]>,
868) -> <Box<[JsValue]> as IntoWasmAbi>::Abi {
869 let js_vals: Box<[JsValue]> = vector.into_vec().into_iter().map(|x| x.into()).collect();
870
871 js_vals.into_abi()
872}
873
874pub unsafe fn js_value_vector_from_abi<T: TryFromJsValue>(
880 js: <Box<[JsValue]> as FromWasmAbi>::Abi,
881) -> Box<[T]> {
882 let js_vals = <Vec<JsValue> as FromWasmAbi>::from_abi(js);
883
884 let mut result = Vec::with_capacity(js_vals.len());
885 for value in js_vals {
886 result.push(
897 T::try_from_js_value(value).expect_throw("array contains a value of the wrong type"),
898 );
899 }
900 result.into_boxed_slice()
901}