ADVENT CALENDAR 2019
【Rust】serde_jsonの使い方
Amusement Creators 2019 アドベントカレンダー 2日目(12/2)の記事です。Rustのserde_jsonを使って, AmCrのメンバーのデータを読み取っていきます。
What is serde_json
?
プログラミング言語Rust
において、Json形式 のデータを楽に読み込んだり、吐き出したりするのにとても便利なcrate(クレート: Rustのライブラリのこと)です。
ちなみに、読み込むことを
Deserialize
, 吐き出すことをSerialize
といいます。
Use easily
Point
構造体のderive
に着目してください。それぞれ、
derive |
意味 |
---|---|
Serialize |
インスタンス->Jsonへの変換を実装する |
Deserialize |
Json->インスタンスへの変換を実装する |
という効果があります。
Detail
serde_json
の機能をもっと詳しく見ていきましょう。
ここでは、members.jsonを読み込むことを目標にします。
serde_json
を使うには、cargo.toml
に次のように設定してください。
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
ひな形
wikiによれば、ここで使われているjsonオブジェクトの形式は、Rustのデータ型を用いて次のように表すことができます。
必須ではないパラメーターを表すには、Option<T>
を使います。
改善
パラメーターのリネーム
現在のままでは、この構造体はパラメーターがスネークケース(snake_case
)で書かれたものにしか対応しません1。パラメーターをリネームして、パスカルケース(PascalCase
)に対応させる必要があります。
といっても、Rustの方針に逆らって構造体のフィールドをリネームする必要はありません。serde_json
には、このような場合にリネームを挟んでくれる機能があります。
#[serde(rename_all = "PascalCase")]
です。この表記(アトリビュートといいます)を、適用するstruct
およびenum
のVariantにつけましょう。
また、表記規則だけでなく、直接パラメーターの名前を変更することもできます。members.json
の中には一箇所だけ適切なパスカルケースにマッチしない部分がありますので(どうしてそんな仕様にした)そこを訂正しましょう。
#[derive(Serialize,Deserialize,Debug)]
#[serde(rename_all = "PascalCase")]
pub struct Member {
name: String,
description: String,
thumbnail: Option<String>,
tags: Option<Vec<String>>,
#[serde(rename="SNS")]
sns: Option<SNS>,
}
enumのシリアライズ
もうひとつ、問題があります。Cluster
列挙体です。
serde_json
のデフォルトの挙動では、Jsonオブジェクトに該当する列挙体のバリアントの名前を書かなくてはなりません。例えば、
let amcr_2018 = Cluster::Active {
year: 2018,
members: Vec::new(),
};
は、
{"Active":{"Year":2018,"Members":[]}}
に対応します(playground)。
これを、
{"Year":2018,"Members":[]}
に対応させるためには、
#[serde(untagged)]
というアトリビュートを列挙体に対して使用します(playground)。
これで必要なデータ型は完成です。
Jsonファイルから読み込む
読み取った文字列をserde_json::from_str()
に代入するという方法もありますが、ファイルから直接インスタンス化する方法もあります。
serde_json::from_reader()
を使います。
let members_json = std::fs::File::open("members.json")?;
let members : members::Members = serde_json::from_reader(members_json)?;
完成
お疲れさまでした。これで、ローカルのmembers.json
2を読み取ることのできるRustのプログラムが完成です。
途中でわからなくなった人もご心配なく。今回の記事のリポジトリを用意しておきました。serde_usage
Advanced
せっかくなので、ローカルのmembers.json
ではなく、github上のものを読み込むようにしてみましょう。reqwestクレートを使います。
実行
$ cargo run
Compiling serde_usage v0.1.0 (/Users/hoge/github/serde_usage)
Finished dev [unoptimized + debuginfo] target(s) in 8.79s
Running `target/debug/serde_usage`
Active: 23, Alumni: 8
自己紹介が掲載されているのは、現役23人・卒業生8人のようです3。
こちらもリポジトリを用意しておきました。Rustの実行環境があれば、git clone
してcargo run
で実行できます。serde_usage/advanced
おわり
serde_json
には、紹介したものの他にも様々な機能があります。examplesを読んでいるだけでも結構面白いので、みなさんも一度は目を通して、必要な機能を把握しておくとよいかもしれません。
SHARE THIS POST
Tweet