1use std::convert::Infallible;
2
3use wasm_bindgen::{JsCast, JsValue};
4
5pub trait FromJs: Sized {
6 type Error;
7 fn from_js(js_value: JsValue) -> Result<Self, Self::Error>;
8}
9
10impl FromJs for JsValue {
11 type Error = Infallible;
12
13 fn from_js(js_value: JsValue) -> Result<Self, Self::Error> {
14 Ok(js_value)
15 }
16}
17
18impl FromJs for () {
19 type Error = JsValue;
20
21 fn from_js(js_value: JsValue) -> Result<Self, Self::Error> {
22 if js_value.is_undefined() {
23 Ok(())
24 } else {
25 Err(js_value)
26 }
27 }
28}
29
30impl<T: FromJs> FromJs for Option<T> {
31 type Error = T::Error;
32
33 fn from_js(js_value: JsValue) -> Result<Self, Self::Error> {
34 if js_value.is_undefined() || js_value.is_null() {
35 Ok(None)
36 } else {
37 T::from_js(js_value).map(Some)
38 }
39 }
40}
41
42macro_rules! impl_from_js {
43 (
44 try_into:
45 $($t:ty)*
46 ) => {$(
47 impl FromJs for $t {
48 type Error = <$t as TryFrom<JsValue>>::Error;
49
50 fn from_js(js_value: JsValue) -> Result<Self, Self::Error> {
51 js_value.try_into()
52 }
53 }
54 )*};
55 (
56 dyn_into:
57 $($t:ty)+
58 ) => {$(
59 impl FromJs for $t {
60 type Error = JsValue;
61
62 fn from_js(js_value: JsValue) -> Result<Self, Self::Error> {
63 js_value.dyn_into()
64 }
65 }
66 )*};
67}
68
69impl_from_js! {
70 try_into:
71 f64
72}
73
74impl_from_js! {
75 dyn_into:
76 js_sys::Intl::Collator
77 js_sys::Intl::DateTimeFormat
78 js_sys::Intl::NumberFormat
79 js_sys::Intl::PluralRules
80 js_sys::WebAssembly::CompileError
81 js_sys::WebAssembly::Global
82 js_sys::WebAssembly::Instance
83 js_sys::WebAssembly::LinkError
84 js_sys::WebAssembly::Memory
85 js_sys::WebAssembly::Module
86 js_sys::WebAssembly::RuntimeError
87 js_sys::WebAssembly::Table
88 js_sys::Array
89 js_sys::ArrayBuffer
90 js_sys::AsyncIterator
92 js_sys::BigInt
93 js_sys::BigInt64Array
94 js_sys::BigUint64Array
95 js_sys::Boolean
96 js_sys::DataView
97 js_sys::Date
98 js_sys::Error
99 js_sys::EvalError
100 js_sys::Float32Array
101 js_sys::Float64Array
102 js_sys::Function
103 js_sys::Generator
104 js_sys::Int8Array
105 js_sys::Int16Array
106 js_sys::Int32Array
107 js_sys::Iterator
110 js_sys::IteratorNext
111 js_sys::JsString
112 js_sys::Map
113 js_sys::Number
114 js_sys::Object
115 js_sys::Promise
116 js_sys::Proxy
117 js_sys::RangeError
118 js_sys::ReferenceError
119 js_sys::RegExp
120 js_sys::Set
121 js_sys::SharedArrayBuffer
122 js_sys::Symbol
123 js_sys::SyntaxError
124 js_sys::TypeError
125 js_sys::Uint8Array
126 js_sys::Uint8ClampedArray
127 js_sys::Uint16Array
128 js_sys::Uint32Array
129 js_sys::UriError
130 js_sys::WeakMap
131 js_sys::WeakSet
132}