🦀

100日後にRustをちょっと知ってる人になる: [Day 75]シリアライズ・デシリアライズ: serde]

2022/12/03に公開

Day 75 のテーマ

Day 74 で紹介をした日時を扱うクレート time の特徴の中で、シリアライゼーションやデシリアライゼーションを行うフレームワークでデファクトスタンダードになっているという serde というクレートについて、名前だけ引用しました。その際にも言っていましたが使ったことがまだないので、今回は serde について学ぼうと思います。

serde

まず最初に以下が serde に関する文書やリポジトリのリンクです。

それでは、serde について book の内容を中心にして見ていきたいと思います。

概要

あらためて、serde が何か?ということから説明します。serde とは、serialization と deserialization を行うたいめのフレームワークです。

serde は、サポートされるデータ構造を、サポートされるデータ形式を使ってシリアライズおよびデシリアライズすることを可能にします。データ構造とデータ形式の間の相互作用は Rust コンパイラによって完全に最適化され、serde によるシリアライズはデータ構造とデータ形式の特定の選択に対して手書きのシリアライザと同じ速度で実行されるようにすることができます。

データ形式

serde は数多くのデータ形式に対応しています。以下のリストは serde に実装されているデータ形式の一部です。

データ構造

serde は Rust 一般的なデータ型に対応していて、上記のデータ形式でシリアライズ・デシリアライズをすることが可能です。例えば、次のような型は全てサポートされています。

  • String
  • &str
  • usize
  • Vec<T>
  • HashMap<K,V>

derive マクロ

serde では、データ構造に対して Serialize および Deserilialze のトレイト実装を生成してくれる derive マクロが提供されています。これによって、serde がサポートしているデータ形式の全てで便利に表現をすることが可能になります。

この derive マクロを使用するためには、Cargo.toml のserde の依存関係でフィーチャーとして derive を追加する必要があります。

cargo add serde --features derive
[dependencies]
serde = { version = "1.0.148", features = ["derive"] }

JSON 形式のシリアライズ / デシリアライズを試してみる

先にも書いていたように serde は様々なデータ形式をサポートしています。しかし、最初に試すのであれば一番馴染みのある JSON 形式を試してみようと思います。

JSON に対応したクレートとして、serde_json があります。

以下のように Cargo.tomlserde_json を追加します。

[dependencies]
serde = { version = "1.0.148", features = ["derive"] }
serde_json = "1.0.89"

シリアライズ / デシリアライズの対象とする構造体に #[derive(Serialize, Deserialize)] を記述しておきます。

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32
}

シリアライズ

serde_json::to_string 関数によって、与えられたデータ構造を JSON の String としてシリアライズします。

let point = Point { x: 1, y: 2};

let serialized = serde_json::to_string(&point).unwrap();
println!("シリアライズ: {serialized}");
実行結果
シリアライズ: {"x":1,"y":2}

デシリアライズ

serde_json::from_str 関数によって、JSON 文字列から T 型のインスタンスでデシリアライズします。

let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("デシリアライズ = {:?}", deserialized);

Day 75 のまとめ

serde を使っていて感じたのが、derive マクロがとても便利でシリアライズ・デシリアライズのトレイトをコンパイル時に自動生成してくれているので簡単のものの場合は特にマクロにまかせてしまえます。コードをシンプルに書けるのは serde の強みかなと思いました。
また、このコンパイル時に自動生成と行っても特に動的リフレクションのようなオーバーヘッドは発生しないようでした。

JSON 形式以外のデータ形式のシリアライズ・デシリアライズも試してみたいなと思いました。

GitHubで編集を提案

Discussion