RustのSerdeでJSONのシリアライズとデシリアライズを行う方法

先生

RustでJSON扱うならSerde一択!シリアライズ/デシリアライズを爆速で実装できる!

RustでJSONを扱う: Serdeの紹介

RustでJSONデータを扱うなら、Serdeクレートは必須のツールです。Serdeは、Rustのデータ構造を効率的にシリアライズ(JSONに変換)およびデシリアライズ(JSONから変換)するための強力なフレームワークを提供します。

この記事では、Serdeを使ってRustでJSONを扱う基本的な方法を、具体的なコード例を交えながら解説します。初心者の方でも理解しやすいように、丁寧に説明していきますので、ぜひ最後までお読みください。

Serdeを使うことで、複雑なデータ構造も簡単にJSONとして扱えるようになり、APIとの連携や設定ファイルの読み込みなどが格段に楽になります。

Serdeのインストールと設定

まず、Serdeをプロジェクトに追加する必要があります。Cargo.tomlファイルに以下の依存関係を追加してください。

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

serdeはシリアライズ/デシリアライズのコア機能を提供し、serde_jsonはJSON形式を扱うためのものです。features = ["derive"]は、deriveマクロを使って構造体や列挙型に自動的にSerdeの実装を追加できるようにするための設定です。

Cargo.tomlを編集したら、cargo buildを実行して依存関係をダウンロードし、プロジェクトをビルドします。

JSONへのシリアライズ

構造体をJSONにシリアライズする例を見てみましょう。

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
    is_student: bool,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let person = Person {
        name: String::from("Alice"),
        age: 30,
        is_student: false,
    };

    let json_string = serde_json::to_string(&person)?;

    println!("{}", json_string);
    Ok(())
}

このコードでは、Person構造体を定義し、#[derive(Serialize, Deserialize)]アノテーションを付与することで、Serdeによるシリアライズ/デシリアライズを自動的に実装しています。

serde_json::to_string(&person)?で、personインスタンスをJSON文字列に変換しています。?はエラーハンドリングのためのもので、変換に失敗した場合にエラーを返します。

実行すると、次のようなJSON文字列が出力されます。

{"name":"Alice","age":30,"is_student":false}

JSONからのデシリアライズ

次に、JSON文字列をRustの構造体にデシリアライズする例を見てみましょう。

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
    is_student: bool,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_string = r#"{"name":"Bob","age":25,"is_student":true}"#;

    let person: Person = serde_json::from_str(json_string)?;

    println!("Name: {}", person.name);
    println!("Age: {}", person.age);
    println!("Is student: {}", person.is_student);
    Ok(())
}

このコードでは、JSON文字列json_stringserde_json::from_str(json_string)?Person構造体のインスタンスに変換しています。型アノテーションPersonは、デシリアライズ先の型を指定するために必要です。

実行すると、次のような出力が得られます。

Name: Bob
Age: 25
Is student: true

より複雑なJSONの扱い

ネストされた構造体やベクタなど、より複雑なデータ構造もSerdeで扱うことができます。

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Address {
    street: String,
    city: String,
}

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u32,
    address: Address,
    hobbies: Vec<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_string = r#"{
        "name": "Charlie",
        "age": 40,
        "address": {
            "street": "123 Main St",
            "city": "Anytown"
        },
        "hobbies": ["reading", "hiking"]
    }"#;

    let person: Person = serde_json::from_str(json_string)?;

    println!("Name: {}", person.name);
    println!("Address: {}, {}", person.address.street, person.address.city);
    println!("Hobbies: {:?}", person.hobbies);
    Ok(())
}

この例では、Address構造体がPerson構造体にネストされており、hobbiesフィールドは文字列のベクタです。Serdeはこれらの複雑なデータ構造も自動的にシリアライズ/デシリアライズできます。

参考リンク

まとめ

この記事では、RustのSerdeクレートを使ってJSONのシリアライズとデシリアライズを行う方法を解説しました。Serdeを使うことで、Rustのデータ構造を簡単にJSONとして扱えるようになり、API連携や設定ファイルの読み込みが非常に簡単になります。

Serdeは非常に柔軟で、様々なカスタマイズオプションも提供しています。より高度な使い方については、Serdeの公式ドキュメントを参照してください。

ぜひSerdeを使いこなして、RustでのJSON処理を効率化してください。