Expand description
A crate to make working with wasm-bindgen
easier.
This crate contains the wasm_bindgen_struct macro which
can be used to declare wasm_bindgen types, and implement
getters/setter as if they were normal rust structs. It can
also be used to implement methods for the type, including inline
mapping to overcome wasm-bindgen-futures limitations.
§Example
// Or you can use this instead to avoid needing to import
// the macro throughout your crate
// #[macro_use]
// extern crate wasm_bindgen_struct;
use wasm_bindgen_struct::wasm_bindgen_struct;
#[wasm_bindgen_struct]
// `module` here means this type comes from the JS "my-module" module
// with the class name `aAnotherType`
#[opts(module = "my-module", js_name = "AnotherType")]
struct MyJsType {
// field names are automatically converted to `camelCase`
field_a: String,
// ...but can be manually specified if needed
#[opts(js_name = "field_b")]
field_b: String,
}
#[wasm_bindgen_struct]
#[opts(module = "my-module")]
impl MyJsType {
// Automatically gets the `static_method_of = MyJsType` applied,
// as well as `catch` due to the `Result`
fn apple() -> Result<String, JsValue>;
// `async` functions in `wasm-bindgen` can only currently return
// `()`, `JsValue`, or Result<_, JsValue>`, where `_` is one of
// the two previously mentioned types. We use `MapValue<T, U>`
// to tell the macro that the binding method should return `T`,
// but we'll map the value to `U`
async fn oranges(&self) -> MapValue<JsValue, String> {
self
.oranges_js()
.await
.unchecked_into::<js_sys::JsString>()
.into()
}
}The above expands to:
// For getters/setters
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(js_name = "AnotherType")]
type MyJsType;
#[wasm_bindgen(
method,
getter,
js_class = "AnotherType",
js_name = "fieldA"
)]
fn field_a(this: &MyJsType) -> String;
#[wasm_bindgen(
method,
setter,
js_class = "AnotherType",
js_name = "fieldA"
)]
fn set_field_a(this: &MyJsType, value: String);
#[wasm_bindgen(
method,
getter,
js_class = "AnotherType",
js_name = "field_b"
)]
fn field_b(this: &MyJsType) -> String;
#[wasm_bindgen(
method,
setter,
js_class = "AnotherType",
js_name = "field_b"
)]
fn set_field_b(this: &MyJsType, value: String);
}
// And for methods
impl MyJsType {
fn apple() -> Result<String, JsValue> {
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(static_method_of = MyJsType, js_name = "apple")]
#[wasm_bindgen(catch)]
fn apple_js() -> Result<String, JsValue>;
}
Self::apple_js()
}
async fn oranges(&self) -> String {
#[wasm_bindgen(module = "my-module")]
extern "C" {
#[wasm_bindgen(method, js_name = "oranges")]
async fn oranges_js(this: &MyJsType) -> JsValue;
}
self
.oranges_js()
.await
.unchecked_into::<js_sys::JsString>()
.into()
}
}§#[opts(...)] on structs
-
dbg:
boolShow the formatted output of the macro as a warning
-
on:
TypeAllows using an existing type with the struct syntax.
§Example
#[wasm_bindgen] extern "C" { type JsType; } #[wasm_bindgen_struct] #[opts(on = JsType)] // Struct can be named anything, it doesn't matter struct JsType { field_1: bool, } -
<unknown>Unknown attributes, such as doc comments, are forwarded to the
type MyTypedeclaration, or ignored in the case of usingon.
§#[opts(...)] on struct fields
§#[opts(...)] on impl
-
dbg: bool
Show the formatted output of the macro as a warning
§#[opts(...)] on impl methods
- constructor:
bool - final_:
bool - structural:
bool - getter:
bool - setter:
bool - indexing_getter:
bool - indexing_setter:
bool - indexing_deleter:
bool - js_name:
Lit - variadic:
bool
§Treatment of Special Types
-
Result<T, E>Implies
catch. -
MapValue<T, U>Allows specifing the types of the generated
wasm-bindgenbinding, as well as the actual method type. This allows arbitrary transformations between the bound method and the output method.§Example
#[wasm_bindgen_struct] struct JsType; #[wasm_bindgen_struct] impl JsType { async fn get_async_string(&self) -> MapValue<JsValue, String> { self .get_async_string_js() .await .unchecked_into::<js_sys::JsString>() .into() } }§Important note
MapValueis a pseudo-type which only exists within the macro’s scope. i.e., this type does not exist outside of#[wasm_bindgen_struct] impl { /* ... */ }and therefore does not need to be imported.