概要
Rust を使ってJsonファイルの読み書きについてのメモ。
とりあえず serde
が有力らしいので使っています。
更新履歴
日付 | 内容 |
---|---|
2022/12/21 | 初版 |
参考
以下の記事を参考にいたしました、ありがとうございます。
Crate serde_json
Serdeのシリアライズ/デシリアライズを試してみる
RustでstructをJSONにシリアライズしてファイルに保存する
環境
Rust 1.65.0 (897e37553 2022-11-02)
serde 1.0
serde_json 1.0
実装
準備
[package]
name = "test01"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
読み込みテスト
以下、読み込みテスト用のJSONファイル
String
, i32
, Vec<u32>
, Struct
からなるテストデータです。
[
{
"Name": "Kiwi",
"Id": 3,
"ItemIdList": [
2000,
2001
],
"RotData": {
"Pitch": 0.0,
"Roll": 0.0,
"Yaw": 0.0
}
},
{
"Name": "Orange",
"Id": 4,
"ItemIdList": [
2002,
2003
],
"RotData": {
"Pitch": 1.0,
"Roll": 50.2,
"Yaw": 66.5
}
}
]
読み込み用コード。
JSON構造に対応した構造体を用意、スネークケースではないため警告が出てしまうのを抑止するためにアトリビュート #[allow(non_snake_case)]
を付与。
use serde::{Serialize, Deserialize};
use std::fs;
use std::io::prelude::*;
// テストパラメータ構造体1
#[derive(Serialize, Deserialize, Debug)]
#[allow(non_snake_case)]
struct Rotator{
Pitch:f32,
Roll:f32,
Yaw:f32,
}
// テストパラメータ構造体2
#[derive(Serialize, Deserialize, Debug)]
#[allow(non_snake_case)]
struct CharaParam {
Name: String,
Id: i32,
ItemIdList: Vec<u32>,
RotData:Rotator,
}
//--------------------------------
// メイン処理
fn main() {
// デシリアライズ
let input_fn = fs::read_to_string("test_input.json")
.expect("JSON Read Failed.");
let deserialized: Vec<CharaParam> = serde_json::from_str(&input_fn).unwrap();
// データ表示
for data in &deserialized {
println!("{:?}", data);
}
}
結果
CharaParam { Name: "Kiwi", Id: 3, ItemIdList: [2000, 2001], RotData: Rotator { Pitch: 0.0, Roll: 0.0, Yaw: 0.0 } }
CharaParam { Name: "Orange", Id: 4, ItemIdList: [2002, 2003], RotData: Rotator { Pitch: 1.0, Roll: 50.2, Yaw: 66.5 } }
書き込みテスト
書き込み用コード。
JSONに対応した構造体を用意し、データもソース直に用意。
use serde::{Serialize, Deserialize};
use std::fs::File;
use std::io::prelude::*;
// テストパラメータ構造体1
#[derive(Serialize, Deserialize, Debug)]
#[allow(non_snake_case)]
struct Rotator{
Pitch:f32,
Roll:f32,
Yaw:f32,
}
// テストパラメータ構造体2
#[derive(Serialize, Deserialize, Debug)]
#[allow(non_snake_case)]
struct CharaParam {
Name: String,
Id: i32,
ItemIdList: Vec<u32>,
RotData:Rotator,
}
//--------------------------------
// メイン処理
fn main() {
// シリアライズ
// データ作成
let chara00 = CharaParam{Name:String::from("Apple"), Id:0x01, ItemIdList:vec![1000, 1001], RotData:Rotator{Pitch:0.0, Roll:0.0, Yaw:32.0} };
let chara01 = CharaParam{Name:String::from("Banana"), Id:0x02, ItemIdList:vec![1002, 1003], RotData:Rotator{Pitch:0.0, Roll:-70.0, Yaw:66.0} };
let mut param_list:Vec<CharaParam> = Vec::new();
param_list.push(chara00);
param_list.push(chara01);
// ファイル出力
let output_fn = String::from("test_output.json");
let result = output_json( &output_fn,param_list);
match result {
Ok(..) => { println!("Json Output Finished. [{}]", output_fn) }
Err(err) => { println!("Error! : {}", err) }
}
}
// jsonファイル書き出し
fn output_json(output_fn: &str, charaparam_list: Vec<CharaParam>) -> std::io::Result<()> {
// シリアライズ
let serialized: String = serde_json::to_string(&charaparam_list).unwrap();
// ファイル出力
let mut file = File::create(output_fn)?;
file.write_all(serialized.as_bytes())?;
Ok(())
}
結果
整形できなかったため、別ツールで別途整形。
[
{
"Name": "Apple",
"Id": 1,
"ItemIdList": [
1000,
1001
],
"RotData": {
"Pitch": 0,
"Roll": 0,
"Yaw": 32
}
},
{
"Name": "Banana",
"Id": 2,
"ItemIdList": [
1002,
1003
],
"RotData": {
"Pitch": 0,
"Roll": -70,
"Yaw": 66
}
}
]
まとめ
Rust勉強中、とりあえずJSONの読み書きができた。
ただ JSONの整形ができなかったため別途jq (https://stedolan.github.io/jq/) を使ったので多少の消化不良感。