ToolConvoyToolConvoyv2.6
DEV

JSON to Rust Struct — JSON から Rust Struct 型を生成

serde を使って JSON から Rust struct 型を生成します。null 許容フィールドには Option、snake_case には rename_all、欠落しうるフィールドには #[serde(default)]——ブラウザ内で完結、アップロード不要。

● ローカル動作 · タブ内で生成ページ読み込み以降のツールによる通信:0件

JSON to Rust Struct

Convert JSON to Rust struct with serde derive macros. Works entirely in your browser.

Rust の型システムは厳格さで有名ですが、serde は JSON を現実的に扱えるようにする橋渡しの役割を担っています。Deserialize derive マクロは、パース処理を代わりに書いてくれるコードジェネレータそのものです。#[derive(Deserialize)] を付けた struct は、serde_json::from_str::<MyStruct>(&json_str)? という 1 回の呼び出しだけで JSON 文字列からインスタンス化でき、しかもコンパイラはコードが動く前にすべてのフィールド型がデシリアライズ可能かどうかを検査します。JSON to Rust Struct ジェネレータは、サンプルの JSON レスポンスを走査して、それに一致する struct を出力します——手作業なら 5 分(フィールドを camelCase から snake_case に直し、Option にするか否かを選び、既定値を設定する)、機械なら 5 ミリ秒で済む作業です。

Rust 特有で分かりにくいのは、命名規則の橋渡しと、default と optional の区別です。Rust の慣習は snake_case(user_id)ですが、JSON の慣習はさまざまです——多くの API は camelCase(userId)を使い、一部は PascalCase(UserId)を使い、社内 API では最初から snake_case のこともあります。serde の rename_all 属性は、この大文字小文字の変換をまとめて処理します。Option と #[serde(default)] の区別はもっと微妙です。Option<T> はフィールドが存在するものの値が null である場合をカバーし、#[serde(default)] はフィールドが JSON オブジェクトから完全に欠落している場合をカバーします。多くの API では、この両方が必要になります。

struct を生成したあとで最もよくある次の手順は、API を扱うために reqwest や ureq に渡すことです。.json::<MyStruct>() でレスポンスボディを直接デシリアライズし、パースは serde に任せます。Tokio を使った非同期 Rust では、共有された可変アクセスのために struct を Arc<RwLock<MyStruct>> で包みます。データベースに接続する場合は、serde の derive と並べて #[derive(sqlx::FromRow)] や Diesel の #[derive(Queryable)] を追加します。生成された struct はデータの契約であり、非同期ランタイム、データベースのマッピング、エラーハンドリングこそが開発者の手で補う部分です。

広告

使い方

  1. JSON を貼り付ける

    JSON オブジェクト、またはオブジェクトの配列を入力欄にドロップします。ジェネレータは構造を走査し、ルートに対して Rust struct を出力し、各オブジェクトの形ごとにネストした struct を生成します。

  2. serde のオプションを選ぶ

    camelCase の JSON キーには `rename_all = camelCase` を、null 許容フィールドには `Option<T>` を、一部の API レスポンスで欠落しうるフィールドには `#[serde(default)]` を切り替えて指定できます。

  3. .rs ファイルをコピーまたはダウンロード

    Rust struct をクリップボードにコピーするか、.rs ファイルとしてダウンロードできます。出力の先頭には `use serde::{Deserialize, Serialize};` が含まれるため、モジュールに貼り付ければそのままコンパイルできます。

よくある質問

なぜ Deserialize と Serialize を derive するのですか?

serde の `#[derive(Deserialize, Serialize)]` は、Rust で JSON の自動シリアライズを有効にする標準的な方法です。`Deserialize` は実行時に JSON を struct へパースするために必須です。`Serialize` は任意ですが、struct が正しくラウンドトリップするよう既定で含めています。

rename_all は JSON キーの大文字小文字をどう扱いますか?

struct レベルに `#[serde(rename_all = "camelCase")]` を書くと、Rust の snake_case のフィールド名(`user_id`)を JSON の camelCase のキー(`userId`)に対応付けるよう serde に指示できます。このリネームはすべてのフィールドに適用されます。個別のフィールドは `#[serde(rename = "custom_name")]` で上書きできます。

null のフィールドと欠落したフィールドはどう扱われますか?

サンプルで null になっているフィールドは `Option<T>` になります。配列の一部の要素で欠落しているフィールドには、`Option<T>` に加えて `#[serde(default)]` が付きます。これにより、JSON にキーが無い場合はパースエラーではなく `None` としてデシリアライズされます。

enum や tagged union はどうなりますか?

ジェネレータは、既知の文字列値の集合から Rust の enum を推論しません。"active"、"pending"、"closed" のいずれかを取る status フィールドは `String` として出力されます。enum と serde の tag は、生成後に手動で定義してください。

chrono や uuid の型には対応していますか?

既定では、ISO 8601 の日付文字列は `String` になります。「chrono」を有効にすると `chrono::NaiveDateTime` を出力し、ISO 8601 形式のための `serde::with` アノテーションを追加します。UUID 文字列も既定では `String` です——使う場合は `uuid` crate を手動で追加してください。

制限事項

  • serde flatten には未対応ジェネレータは、親の階層にインライン展開すべきネストした JSON オブジェクトに対して `#[serde(flatten)]` を使いません。ネストが深いものの、アプリケーション側ではフラットに扱う API の場合は、手動で flatten を追加してください。
  • ジェネリック型パラメータには未対応出力は具体的なフィールド型を持つ具体的な struct です。多態的な JSON レスポンス(例:`{ "type": "image", "data": ... }`)には、serde の internally tagged 表現を用いた enum を手書きする必要があります。
  • 借用は考慮されないすべてのフィールド型は自身のデータを所有します(String、Vec など)。ライフタイムや借用は使いません。`Cow<'_, str>` によるゼロコピーのデシリアライズを行う場合は、ライフタイムと `#[serde(borrow)]` アノテーションを手動で追加してください。

プラットフォーム別の注意点

macOS
RustRover、rust-analyzer を入れた VS Code、Rust 対応の vim は、いずれも生成された struct をそのまま扱えます。API を調べている最中に、サンプルレスポンスから一回限りの生成を行うにはブラウザツールが便利です。
Windows
生成された struct は、どの Rust ツールチェーンでもコンパイルできます。本格的な IDE を開かずに一回限りの struct 生成をしたいときは、ブラウザツールが便利です。
Linux
コマンドライン作業では、`quicktype --lang rust` や `serde-generate` が同様の出力を生成します。Rust をインストールできない環境での一回限りの生成には、ブラウザツールが適しています。
Web
完全にクライアントサイドで動作します。生成は数ミリ秒で終わります。
広告
広告