Short introduction to wasm-bindgen
WebAssembly is limited to basic integer and float types, but does not itself support rich types like strings, objects, enums or closures. However an instantiated WebAssembly module has access to memory where it can place more data. This block of memory is also accessible by the host side, e.g. the JavaScript environment of a website. Both sides, the WebAssembly code and the host side, need to agree what bytes in that memory block mean in order to work with them.
wasm-bindgen
is a tool that can generate the necessary code on both sides
to handle more rich types.
It supports a variety of Rust types, including String
, Vec
, Result
and slices,
and allows to export Rust types for use in JavaScript (see wasm-bindgen
's Supported Rust types).
How to use
The wasm-bindgen
CLI utility works on the compiled .wasm
file.
It supports several different output targets.
For this tutorial we focus only on JavaScript and the web
target.
wasm-bindgen path/to/module.wasm --out-dir app --target web --no-typescript
#[wasm_bindgen(start)]
This annotation should be put on a public function.
That function essentially becomes your start
function,
which gets automatically called when you instantiate the WebAssembly module.
You would for example use this to set up a panic handler and logging.
#[wasm_bindgen(start)]
pub fn main() {
panic::set_hook(Box::new(console_error_panic_hook::hook));
console_log::init_with_level(log::Level::Debug).unwrap();
}
#[wasm_bindgen]
on a function
If used without additional attributes this wraps the annotated function
to be exported.
You can use the supported Rust types and wasm-bindgen
will ensure the conversion happens on either side.
#[wasm_bindgen]
pub fn say_hello(name: String) -> String {
format!("Hello, {}", name)
}
#[wasm_bindgen]
on a struct
Annotating a Rust struct
makes that struct available on the JavaScript side as an object.
#[wasm_bindgen]
struct Country {
string shortcode;
}
Methods of that struct need to be annotated to be available in JavaScript, too.
impl Country {
#[wasm_bindgen(constructor)]
pub fn new() -> Country {
Country { shortcode: "NO".to_string() }
}
#[wasm_bindgen(getter)]
pub fn shortcode(&self) -> String {
self.shortcode.clone()
}
}
The tutorial won't use this, but feel free to play around.
See On Rust exports in the wasm-bindgen
documentation for more.
In the next chapter you will start building the image filter application for the web,
using wasm-bindgen
to help with the rich types.