A crate to make working with [`wasm-bindgen`](https://crates.io/crates/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 ```rust // 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; // `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` // to tell the macro that the binding method should return `T`, // but we'll map the value to `U` async fn oranges(&self) -> MapValue { self .oranges_js() .await .unchecked_into::() .into() } } ``` The above expands to: ```rust // 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 { #[wasm_bindgen(module = "my-module")] extern "C" { #[wasm_bindgen(static_method_of = MyJsType, js_name = "apple")] #[wasm_bindgen(catch)] fn apple_js() -> Result; } 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::() .into() } } ``` # `#[opts(...)]` on structs - dbg: `bool` Show the formatted output of the macro as a warning - on: `Type` Allows using an existing type with the struct syntax. ## Example ```rust #[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, } ``` - [extends: `Type`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/extends.html) - [getter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [setter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [final\_: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/final.html) - [js_name: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_name.html) - [js_namespacejsnamespace: Vec: `[Lit1, Lit2, Lit3, ...]`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_namespace.html) - [module: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/module.html) - [raw_module: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/raw_module.html) - _``_ 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 - [getter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [setter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [structural: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/structural.html) - [final\_: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/final.html) - [js_name: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_name.html) # `#[opts(...)]` on `impl` - dbg: bool Show the formatted output of the macro as a warning - [final\_: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/final.html) - [js_name: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_name.html) - [js_namespace: `[Lit1, Lit2, Lit3, ...]`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_namespace.html) - [module: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/module.html) - [raw_module: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/raw_module.html) # `#[opts(...)]` on `impl` methods - [constructor: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/constructor.html) - [final\_: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/final.html) - [structural: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/structural.html) - [getter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [setter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/getter-and-setter.html) - [indexing_getter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/indexing-getter-setter-deleter.html) - [indexing_setter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/indexing-getter-setter-deleter.html) - [indexing_deleter: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/indexing-getter-setter-deleter.html) - [js_name: `Lit`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/js_name.html) - [variadic: `bool`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/variadic.html) # Treatment of Special Types - `Result` Implies [`catch`](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/catch.html). - `MapValue` 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. ## Example ```rust #[wasm_bindgen_struct] struct JsType; #[wasm_bindgen_struct] impl JsType { async fn get_async_string(&self) -> MapValue { self .get_async_string_js() .await .unchecked_into::() .into() } } ``` ### Important note `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.