LoginSignup
2
1

More than 3 years have passed since last update.

Rust+wasmでJSONを扱う

Posted at

Rust+wasmで複雑なものを作ろうとするとJSON形式のデータは避けて通れないと思いますが、wasm-bindgenのドキュメントにあるJsValueを使うのがよさそうです。

Cargo.toml
[dependencies]
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
lib.rs
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Monster {
    name: String,
    value: String
}

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

#[wasm_bindgen]
pub fn return_name(val: &JsValue){
    let m: Monster = val.into_serde().unwrap();
    //alert(&m.name);
    console_log(&m.name);
    console_log(&m.value);
}

dependenciesでwasm-bindgenのバージョンだけでなくserde-seriarizeというfeatureも指定する必要があります。(これを読み飛ばしてて、気付くまで時間かかった・・・)

return_nameの引数のval: &JsValueが今回のキモです。今回はinto_serde()でJSONを読み込んでますが、逆にRustの値をJSONにするfrom_serde()というメソッドもサポートしてます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
        import * as mod  from "./wasm.js";
        let monster = {
          "name":"pikachu",
          "value":"100"
        };
        (async () => {
            await mod.default();
            mod.return_name(monster);
        })();
    </script>
    <script>
      const console_log = (val) => {
        console.log(val);
      }
    </script>
  </body>
</html>

次にJavaScript側です。wasm.jsから読み込んだRustの関数(return_name)にmonsterという値をそのまま渡します。

rust.png

絵にすると、こんな感じです。Rustで書いたreturn_nameという関数をJavaScriptのasyncの中で呼び出し、そのreturn_nameではJavaScriptで書いたconsole_logという関数を呼び出しています。

これでJavaScriptで生成した大量のデータをwasmで処理できますね。

環境のインストールとビルドは、こちらの記事が参考になると思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1