本文へスキップ

JSONからRust SerdeStructsへの変換 — Numio

JSON サンプルから、serde の Serialize と Deserialize を derive した Rust の struct を生成します。フィールドは rename_all 属性付きの snake_case になり、配列の一部の要素にしかないキーは Option<T>、null 値は serde_json::Value になります。

reqwest クライアントで serde_json を使ってデシリアライズする前に、サードパーティ API のレスポンスに型を付ける。

JSON

Rust Serde

こんなときに使えます

  • reqwest クライアントで serde_json を使ってデシリアライズする前に、サードパーティ API のレスポンスに型を付ける。
  • Rust の CLI や Axum サービスで使う JSON 設定ファイルやフィクスチャの struct を書く。

使い方

  1. JSON サンプルを貼り付けます。省略可能なフィールドがある場合は、そのフィールドを持つ配列要素と持たない要素の両方を含めます。
  2. 設定を開き、JSON のキーの書き方に合わせて Property Name Format を選びます(既定は camelCase)。これで #[serde(rename_all = ...)] が決まり、合わないキーには #[serde(rename = ...)] が付きます。
  3. コードをコピーし、生成された use 行に合わせて Cargo.toml に serde(derive 付き)、serde_derive、serde_json を追加します。

JSON 入力

{
  "orderId": "A-1001",
  "total": 19.5,
  "paid": true,
  "coupon": null,
  "items": [
    { "sku": "PEN-01", "qty": 2 },
    { "sku": "BOOK-7", "qty": 1, "giftWrap": true }
  ]
}

Rust struct(serde)

use serde_derive::Deserialize;
use serde_derive::Serialize;
use serde_json::Value;

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
    pub order_id: String,
    pub total: f64,
    pub paid: bool,
    pub coupon: Value,
    pub items: Vec<Item>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Item {
    pub sku: String,
    pub qty: i64,
    pub gift_wrap: Option<bool>,
}

仕様と制限

生成はブラウザ内で json_typegen の WebAssembly モジュールにより行われ、サーバーには何も送信されません。

整数は i64、小数は f64 になります。null と空配列は serde_json::Value と Vec<Value> になるので、Option<String> などの具体的な型に置き換えてください。

Rust のキーワードは名前が変わります。type というキーは type_field になり、#[serde(rename = "type")] が付きます。

すべての struct は Serialize と Deserialize に加えて Default、Debug、Clone、PartialEq も derive します。不要なものは削除してください。

FAQ

Property Name Format の設定で何が変わりますか?

Rust のフィールド名ではなく、JSON のキーの書き方を指定します。フィールドは常に snake_case で、この設定によって rename_all の値が決まり、serde が camelCase、kebab-case、PascalCase などに対応付けます。

省略可能なフィールドはどう判定されますか?

同じ配列内のオブジェクトでキーが異なる場合、一部の要素にしかないキーが Option<T> になります。サンプルのすべての要素にあるフィールドは、API が省略することがあっても省略可能にはなりません。

JSON のルートは配列でもかまいませんか?

はい。ルート配列からは pub type Root = Vec<Root2>; と、要素を表す struct Root2 が生成されます。

仕様を確認する