昨日の続きです。
Rust+wasmでJSONを扱うにはwasm_bindgenのJsValue型が使えると書きましたが、JSONに格納されている配列のデータを扱うには、もうひと工夫が必要です。
lib.rs
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
# [derive(Serialize, Deserialize)]
pub struct Monster {
name: String,
value: String
}
# [derive(Serialize, Deserialize)]
pub struct Monsters {
monsters: Vec<Monster>
}
# [wasm_bindgen]
extern {
pub fn alert(s: &str);
pub fn console_log(s: &str);
}
# [wasm_bindgen]
pub fn return_name(val: &JsValue){
let monsters: Monsters = val.into_serde().unwrap();
let mut max_val: usize = 0;
let mut max_val_monster = Monster{
name: String::new(),
value: String::new()
};
let mut monster_name = String::new();
for monster in monsters.monsters {
let val: usize = monster.value.parse().unwrap();
if val > max_val {
max_val = val;
monster_name = monster.name;
}
}
console_log(&format!("{}",monster_name));
console_log(&format!("{}",max_val));
}
昨日のコードではMonsterというstructだけ用意しましたが、MonsterをメンバとするMonstersというstructを用意して、こちらにinto_serde()を使って読み込みます。
なお、昨日のコードではreturn_name()では名前だけ返してましたが、同じ関数ですがvalueが最大のモンスターの名前を返すことにしています。
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 monsters = {
"monsters":[
{"name":"pikachu","value":"10"},
{"name":"eevee","value":"99"}
]
};
(async () => {
await mod.default();
mod.return_name(monsters);
})();
</script>
<script>
const console_log = (val) => {
console.log(val);
}
</script>
</body>
</html>
こちらでJSONに配列を入れてます。これで少しは汎用的になったでしょうか。