Crates.io | wasm-bindgen-struct |
lib.rs | wasm-bindgen-struct |
version | 0.1.0 |
source | src |
created_at | 2023-05-01 14:41:43.931724 |
updated_at | 2023-05-01 14:41:43.931724 |
description | Macro to make declaring `wasm-bindgen` imports much easier. |
homepage | |
repository | https://github.com/jquesada2016/wasm-bindgen-struct |
max_upload_size | |
id | 853439 |
size | 55,687 |
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.
// 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 structsdbg: bool
Show the formatted output of the macro as a warning
on: Type
Allows using an existing type with the struct syntax.
#[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 MyType
declaration, or ignored in the case of using
on
.
#[opts(...)]
on struct fields#[opts(...)]
on impl
dbg: bool
Show the formatted output of the macro as a warning
#[opts(...)]
on impl
methodsbool
bool
bool
bool
bool
bool
bool
bool
Lit
bool
Result<T, E>
Implies catch
.
MapValue<T, U>
Allows specifing the types of the generated wasm-bindgen
binding, as well as the actual method type. This allows
arbitrary transformations between the bound method and the
output method.
#[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()
}
}
MapValue
is 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.