If I create a Rust function with wasm_bindgen that accepts an HtmlCanvasElement
, how do I make sure it fails when it gets to the Rust side?
JavaScript:
(async () => {
const demo = await import('./pkg/demo').catch(console.error);
demo.setCanvas('Hello Element!');
})();
Rust:
use wasm_bindgen::prelude::*;
use web_sys::{console, HtmlCanvasElement};
#[wasm_bindgen]
pub fn setCanvas(canvas: &HtmlCanvasElement) {
// Why does this even get here? I didn't pass in an HtmlCanvasElement
console::log_1(&canvas);
}
It looks like I'm getting the type HtmlCanvasElement
but if I try to use it as an HtmlCanvasElement
, it doesn't have the functions because I'm passing in a string instead of the actual canvas element. I want it to fail when I set it, not at some later time when I try to use it.
There's not much type control at the boundary between the DOM and Rust in wasm_bindgen. The JavaScript part handles what is seen from Rust as JsValue
.
It means you have to do the checked conversions yourself (or let a future lib or framework do it for you).
The JsCast
trait helps for this. It lets you write this for example:
#[wasm_bindgen]
pub fn setElement(canvas: JsValue) -> Result<(), JsValue> {
match canvas.dyn_into::<HtmlCanvasElement>() {
Ok(canvas) => {
// ...
Ok(())
}
Err(_) => Err(JsValue::from_str("argument not a HtmlCanvas")),
}
}