RustのクレートをWebAssemblyに取り込む
前回記事で、Rustにさまざまな機能を提供するライブラリー「クレート」を紹介しました。そこでクレートをWebAssemblyに取り込んで利用する例を、入力文字列のSHA-2(SHA-256)ハッシュを求める図4のサンプルで説明します。
Rustのプロジェクト(p003-use-crate)を生成後、プロジェクト設定ファイルCargo.tomlにリスト13の通りクレートを指定します。このサンプルでは、SHA-2ハッシュを求める「sha2」と、16進数文字列を求める「base16」の、2つのクレートを利用します。
[dependencies] wasm-bindgen = "0.2.63" # 元からあるもの sha2 = "0.10.2" # 追加 base16 = "0.2.1" # 追加
Rustの実装はリスト14の通りです。
use wasm_bindgen::prelude::*; use sha2::{Sha256, Digest}; // sha2クレート ...(1) use base16; // base16クレート ...(2) (略) // SHA-2の計算処理 ...(3) #[wasm_bindgen] pub fn sha2(input: String) -> String { // SHA-2処理オブジェクトを生成 ...(4) let mut hasher = Sha256::new(); // ハッシュ計算 ...(5) hasher.update(input); // 計算結果を出力 ...(6) let hash = hasher.finalize(); // 計算結果を16進文字列に変換 ...(7) let encoded = base16::encode_lower(&hash); // 16進文字列を返却 return encoded; }
まず(1)と(2)で、使用するクレートを記述します。SHA-2の計算処理(3)では、(4)のSha256::newメソッドでSHA-2(SHA-256)を計算するオブジェクトhasherを生成し、(5)でupdateメソッドに入力文字列inputを与えてハッシュを計算します。計算結果を(6)のfinalizeメソッドで取得後、(7)のbase16::encode_lowerメソッドで小文字の16進文字列に変換して返却します。
一方、Webページのプロジェクト(p003-use-crate-web)では、WebAssemblyの処理を実行する処理をindex.jsにリスト15の通り実装します。
// WASMをインポート ...(1) import * as wasm from 'p003-use-crate'; // WASMによるSHA-2の処理 ...(2) document.getElementById('sha2-input') .addEventListener('input', e => { // 入力値を取得 ...(3) const input = e.target.value // SHA-2を計算 ...(4) const hash = wasm.sha2(input); // 計算結果を表示 ...(5) document.getElementById('sha2-result').textContent = hash; });
リスト14をビルドして作成したパッケージを(1)でインポートします。テキストボックス入力時のイベント処理(2)では、(3)で入力値を取得し、(4)でSHA-2を計算、(5)で計算結果を表示します。
まとめ
本記事では、RustでWebAssemblyを実装する方法を説明しました。加えて、ライプニッツの公式を利用した円周率の計算を例に、WebAssemblyとJavaScriptの速度比較を行いました。また、RustのクレートをWebAssemblyに組み込む方法も説明しました。
今回利用したWebAssemblyでは、JavaScriptとやり取りするデータは数値や文字列といった単純なものでした。より実践的にWebAssemblyを利用するには、WebAssemblyとJavaScriptとの間でさまざまなデータをやり取りする必要があります。そこで次回は、JavaScriptとRustでデータをやり取りする方法を、より詳細に説明していきます。