はじめてのwasm-bindgen


前回の記事では、とにかくコピペでRustからWasmを出力、webページとして確認することができました

そこで使った以下のRustコードを解説します

lib.rs
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}

1~3行目 クレートの記述

extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

この部分はWasmというよりRustのクレートに関する記述ですね
実はこれアドベントカレンダーでして、2日目の記事で少し触れたのですがもう少し具体的に見てみましょう

externキーワードで、外部のクレートを用いることを示しています
そしてuseキーワードで実際にwasm_bindgenの内preludeというモジュールの全てを使用する、と伝えています

wasm_bindgenはRustとJavaScriptの繋ぎ役です。Rustの型や関数をJavaScriptの型や関数に、JavaScriptの型や関数をRustの型や関数にしてくれます。実際の使い方は次です

真ん中あたり JSの関数をもらう

この部分です

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

ここではJavaScriptのalert()関数をつかうよーと指示しています。
最初の#[]はアトリビュートと呼ばれexternと組み合わさると、中のwasm_bindgenから関数を引っ張ってくるよ、という意味になります。つまり、ここは「wasm_bindgenが持ってるalert()を読み込む」という旨です。

下の方 使わせたいRust

最後にこちら

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}

ここでは同じようにアトリビュートを使用していますが、今度はexternがないので逆に「このRust関数をJSで使ってください」という意味になります。そこではgreetという、nameで引数を取る関数を渡しています。
ややこしいですが関数の中身で上記のもらってきたalert関数を使っています。もらってきたので単なるRustですが。

alert関数には文字列の引数を渡せばいいのですが、ここはRustの世界なのでformat!()というマクロを使ってnameの値を含む文字列を生成してから渡していますね。マクロってなに?

最小のサンプルなのでJSを取り込んでRustを書き、RustをJSに引き渡す、というコードですが、気にせずにWebの機能を使いたければwasm-bindgenから呼び出し、Rustで行いたい処理を記述したあとJSで実行してもらうという流れで良いと思います。

個別に見ていけば簡単な処理ですし、これだけでRustがWebで動くということも実感できます