Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

この記事は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の紹介もあります。

fujitayy
wano-inc
「Cultivate your dream」をミッションにクリエイター・アーティストを支援する事業やサービスを展開
https://wano.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした