LoginSignup
0
1

More than 1 year has passed since last update.

Vue.jsでwasm-bindgen(Rust+WebAssembly)の入出力を扱う(CSV編)

Last updated at Posted at 2020-09-22

前に「Vue.jsでwasm-bindgen(Rust+WebAssembly)の入出力を扱う」という記事を書いたが、CSVで読み込めた方が色々と楽だ。

作成中のプログラムからCSVに関するところだけ抜き取ったので動作保証はできないが、雰囲気だけ感じていただければと思う。

環境構築は、こちらを参考に。

変更はConfit.tomlにcsvを追加するぐらいかな。

CSVは、こんな感じの形式。

monster.csv
name,cost
ピカチュウ,10
イーブイ,9

前回と同じようにVue.jsでボタンを押すと発動するようにしておく。今回は手抜きでRust側からconsole.log()を呼ぶためにlog()という関数を定義しておく。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>wasm_csv_test</title>
  </head>
  <body>
    <div id="app">
      <button v-on:click="csvtest">test</button>
    </div>
    <script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="index.js" type="module"></script>
    <script>
      const log = (val) => {console.log(val);}
    </script>
  </body>
</html>

index.jsではmounted:の中でCSVファイルを読み込んでおき、ボタンを押したらRustで定義したcsv_test()にCSVの中身を渡す。

index.js
import * as mod from "./wasm.js";
(async () => {
    await mod.default();
    var app = new Vue({
      el: '#app',
      data: {
        csv: null
      },
      mounted: function(){
        axios.get("./monster.csv").then(
          response => ( this.csv = response.data )
        );
      },
      methods:{
        csvtest: function(event){
          mod.csv_test(this.csv);
        }
      }
    })
})();

次にRust側。Monster(単体)とMonsters(複数)のstructを作っておく。

monster.rs
#[derive(Clone)]
pub struct Monster {
    pub id: usize,
    pub name: String,
    pub cost: usize,
}

#[derive(Clone)]
pub struct Monsters {
    pub monsters: Vec<Monster>
}

impl Monsters {
    pub fn new() -> Self {
        Monsters {
            monsters: Vec::new()
        }
    }
    pub fn add_monster(&mut self, m: Monster){
        self.monsters.push(m);
    }
}

lib.rsではcsv::ReaderBuilder::new().delimiter(b',').from_reader(data.as_bytes())でCSVファイルを読み込み、Monsterに格納しながらlog()経由でブラウザのconsole.log()に出力する。

lib.rs
pub mod monster;

use wasm_bindgen::prelude::*;
use crate::monster::*;

#[wasm_bindgen]
pub fn csv_test(data: &str) {

    let mut m = Monsters::new();
    let mut r = csv::ReaderBuilder::new().delimiter(b',').from_reader(data.as_bytes());
    let mut id :usize = 0;

    for record in r.records(){
        let record = record.unwrap();
        m.add_monster(
            Monster {
                id: id,
                name: record[0].to_string(),
                cost: record[1].parse().unwrap(),
            }    
        );
        id = id + 1;
        log(&format!("{}",&record[0]));
    }
}

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

今回はidの値をCSVと外で生成しているが、もしCSVの形式とstructが完全一致であればSerdeのdeserializeで一気に格納することもできる。

この仕組みを使って、ドラクエウォークのモンスターの最適な組み合わせを計算するサイトを作ってみたので、参考にしていただきたい。

0
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
0
1