1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*!
This is a specialized crate exporting a derive macro [`TryFromJsValue`]
that serves as a basis for workarounds for some lapses of functionality in
[`wasm-bindgen`](https://crates.io/crates/wasm-bindgen).
## Optional arguments and return values
`wasm-bindgen` supports method arguments of the form `Option<T>`,
where `T` is an exported type, but it has an unexpected side effect on the JS side:
the value passed to a method this way gets consumed (mimicking Rust semantics).
See [wasm-bindgen#2370](https://github.com/rustwasm/wasm-bindgen/issues/2370).
`Option<&T>` is not currently supported, but an equivalent behavior can be implemented manually.
```
use js_sys::Error;
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
use wasm_bindgen_derive::{TryFromJsValue, try_from_js_option, into_js_option};
// Derive `TryFromJsValue` for the target structure (note that it has to come
// before the `[#wasm_bindgen]` attribute, and requires `Clone`):
#[derive(TryFromJsValue)]
#[wasm_bindgen]
#[derive(Clone)]
struct MyType(usize);
// To have a correct typing annotation generated for TypeScript, declare a custom type.
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "MyType | undefined")]
pub type OptionMyType;
}
// Use this type in the function signature.
#[wasm_bindgen]
pub fn option_example(value: &OptionMyType) -> Result<OptionMyType, Error> {
// Use a helper to extract the typed value
let typed_value = try_from_js_option::<MyType>(value).map_err(|err| Error::new(&err))?;
// Now we have `typed_value: Option<MyType>`.
// Return it
// Note that if `typed_value` is `None`, `into_js_option()` creates a `JsValue::UNDEFINED`.
Ok(into_js_option(typed_value))
}
```
## Vector arguments
With the closing of [wasm-bindgen#111](https://github.com/rustwasm/wasm-bindgen/issues/111),
it is now possible to return `Vec<MyType>` values.
Having an argument of type `Vec<MyType>` compiles, but results in an unexpected behavior
similar to that with `Option<MyType>`: all the elements of the input array
(but not the array itself) are invalidated on the JS side.
So this crate can still be used to take array arguments without invalidating them.
```
use js_sys::Error;
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
use wasm_bindgen_derive::{TryFromJsValue, try_from_js_array, into_js_array};
#[derive(TryFromJsValue)]
#[wasm_bindgen]
#[derive(Clone)]
struct MyType(usize);
// To have a correct typing annotation generated for TypeScript, declare a custom type.
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "MyType[]")]
pub type MyTypeArray;
}
// Use this type in the function signature.
#[wasm_bindgen]
pub fn vec_example(val: &MyTypeArray) -> Result<MyTypeArray, Error> {
// Use a helper to extract the typed array
let typed_array = try_from_js_array::<MyType>(val).map_err(|err| Error::new(&err))?;
// Now we have `typed_array: Vec<MyType>`.
// Return the array
Ok(into_js_array(typed_array))
}
// Post wasm-bindgen 0.2.91, we can just return a vector
#[wasm_bindgen]
pub fn vec_example_simplified(val: &MyTypeArray) -> Result<Vec<MyType>, Error> {
// Use a helper to extract the typed array
let typed_array = try_from_js_array::<MyType>(val).map_err(|err| Error::new(&err))?;
// Now we have `typed_array: Vec<MyType>`.
// Return the array
Ok(typed_array)
}
```
*/
// Needed for the generated code to work.
/// Re-exported standard library `alloc` to use in the generated code.
pub extern crate alloc;
pub use ;
pub use TryFromJsValue;