LoginSignup
20
10

More than 5 years have passed since last update.

RustでデータをJSONやYAML等にserialize/deserializeする方法

Last updated at Posted at 2018-12-03

この記事はWanoアドベントカレンダーの4日目の記事です。

TL;DR

  • 使うcrate
  • serdeはserialize/deserializeの為の仕組みを提供する
  • serde_json等の各フォーマット毎のserdeに対応したcrateを使って具体的なフォーマットとの変換を行う

Rustでserialize/deserializeを行うには

serdeserde_deriveというcrateを使います。
この2つのcrateを使ってSerialize/Deserialize traitを構造体などに実装する事でserializeが出来るようになります。
serde_deriveが自動実装のマクロを提供しているので、ユーザーは構造体等の定義の上に#[derive(Serialize, Deserialize)]と書くだけでOKです。

JSONとのserialize/deserializeを実装してみる

serialize

まずはJSONへのserializeを実装してみましょう。
$ cargo new serde_exampleという感じでプロジェクトを作ります。
できましたら今作ったプロジェクトのディレクトリに移動して($ cd serde_example)、Cargo.tomlを開いて[dependencies]の下に次の3行を追加します。

serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"

次にsrc/main.rsを開いて次の様に編集します。

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

#[derive(Debug, Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
}

fn main() -> Result<(), Box<std::error::Error>> {
    let tarou = Person { name: "太郎".to_string(), age: 18 };
    let json = serde_json::to_string(&tarou)?;
    println!("{}", json);

    Ok(())
}

$ cargo runで実行します。

必要なcrateをダウンロードしたりコンパイルしたり等のメッセージが色々出てると思いますが、最後に次のテキストが表示されていれば成功です。

{"name":"太郎","age":18}

これでJSONへのシリアライズが出来ました。

ユーザーは構造体等の上に#[derive(Serialize, Deserialize)]と書き(必要に応じて他のtrait等も一緒に書く)、SerializeDeserializeを実装します。
実装したらserdeに対応している目的のフォーマット用のcrateで実際に変換します。
ここではserde_jsonがこれに当たり、serde_json::to_string(&tarou)とすることで構造体からJSONへと変換しています。

deserialize

次にJSONからのdeserializeを実装してみましょう。
上で編集したmain.rsmain関数を次の様に変更します。

fn main() -> Result<(), Box<std::error::Error>> {
    let tarou = Person { name: "太郎".to_string(), age: 18 };
    let json = serde_json::to_string(&tarou)?;
    println!("{}", json);

    // ここが追加分
    let json = r#"{ "name": "花子", "age": 68 }"#;
    let hanako: Person = serde_json::from_str(json)?;
    println!("{:?}", hanako);

    Ok(())
}

$ cargo runで実行します。

{"name":"太郎","age":18}
Person { name: "花子", age: 68 }

Person {~}の行が増えました。JSON文字列から構造体に正しく変換できています。

serdeに対応したcrate

serdeに対応しているcrateには次の様な物があります。

Format crate github
JSON serde_json https://github.com/serde-rs/json
YAML serde_yaml https://github.com/dtolnay/serde-yaml
MessagePack rmp, rmp-serialize, rmps, rmpv https://github.com/3Hren/msgpack-rust
TOML toml https://github.com/alexcrichton/toml-rs
x-www-form-urlencoded serde_urlencoded https://github.com/nox/serde_urlencoded

serdeのドキュメントにその他の形式のcrateの紹介もあります。

20
10
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
20
10