個人的にWebAssemblyには強く期待しており、その中でもGoが有力だと感じています。それはGoのWebAssemblyではDOMやJavaScript APIが使えるからです。駆使すればWebアプリケーション全体のコードをGoで書けるのです。これがRustにもないのが残念でした。 しかしwasm-moduleが新しい可能性を見せてくれます。wasm-moduleはRustでもDOM操作を可能にしてくれるのです。

wasm-moduleの使い方

コンソールにメッセージを出すデモ。

コードはこのようになります。

extern "C" {
    fn console_log(start: i32);
}

fn cstr(s:&str) -> i32{
    std::ffi::CString::new(s).unwrap().into_raw() as i32
}

#[no_mangle]
pub fn main() -> () {
    unsafe {
        console_log(cstr("hello world!"));
    }
}

さらにCanvasを使うことも。

入力値だって扱えます。

wasm-moduleは独自のタグ <wasm -module></wasm> を使ってWebAssemblyファイルを読み込みます。それによってライブラリを読み込み、WebAssembly内でDOMを使えるようになります。

extern "C" {
    fn global_getWindow() -> i32;
    fn Window_get_document(window:i32) -> i32;
    fn Document_querySelector(document:i32,query:i32) -> i32;
    fn HTMLCanvasElement_getContext(element:i32,context:i32) -> i32;
    fn CanvasRenderingContext2D_fillText(canvas:i32,msg:i32,x:i32,y:i32);
}

fn cstr(s:&str) -> i32{
    std::ffi::CString::new(s).unwrap().into_raw() as i32
}

#[no_mangle]
pub fn main() -> () {
    unsafe {
        let w = global_getWindow();
        let d = Window_get_document(w);
        let canvas = Document_querySelector(d,cstr("#screen"));
        let ctx = HTMLCanvasElement_getContext(canvas,cstr("2d"));
        CanvasRenderingContext2D_fillText(ctx,cstr("hello world!"),50,50);
    }
}

コードはちょっと取っつきが悪そうな気はしますが、wasm-moduleのラッパーも登場するのではないでしょうか。そうすれば状況は大きく変わって、RustでWebアプリケーションを書く流れすらできそうです。

wasm-moduleはRust製のオープンソース・ソフトウェア(MIT License)です。

richardanaya/wasm-module: write web assembly that uses that dom easily