本文へスキップ

JSONからRust構造体

JSON to Rust Structs

JSONの実例からserde属性付きのRust構造体を作り、空や欠けうるフィールドはOptionに、キー名はsnake_caseへのrenameで処理します。

例のJSON文書から`serde`のderiveが付いたRustの構造体を出します。`Serialize`と`Deserialize`、ときどき欠けていたフィールドに付く`Option<…>`、そしてJSONのキーがsnake_caseのフィールド名として使えないところの`#[serde(rename = "…")]`まで、まとめて出ます。

🔒 ブラウザの中だけで動きますrustjsoncodegenserde
出力する形式

サンプルJSON

.json ファイルを置く

このタブの中で読みます。アップロードはしません。

手元にある要素を全部入れてください。レコードが一つ増えるたびに推論が絞り込まれます。どれか一つに無いフィールドこそが、省略可能である根拠です。

Rust

使い方

  1. 手元にあるレコードをできるだけ多く貼り付けます

    配列は先頭の要素だけでなく、すべての要素を読んで合わせます。レコードが3件あれば1件のときよりはるかに多くのことが分かります。どれか1件に欠けているという事実こそが、そのフィールドを省略可能にする根拠だからです。

  2. ルートの型に名前を付けます

    入れ子のオブジェクトは、それを保持しているキーの名前を取ります。配列なら単数形になるので、`users`からは`User`ができます。自分で名前を決める必要があるのはルートだけです。

  3. 出力の下にある件数を読みます

    型の数、省略可能なフィールドの数、ユニオンの数、そして合わせたレコードの数が出ます。ユニオンが0より大きければ、あるフィールドが標本の中で違う種類の値を持っていたということなので、結果をコードベースに貼り付ける前に一度見ておく価値があります。

  4. 構造体をクレートに貼り付けます

    `use serde::{Deserialize, Serialize};`の行は一緒に出ます。クレート本体と`derive`フィーチャは、自分でCargo.tomlに追加してください。

よくある質問

あるフィールドが`serde_json::Value`になったのはなぜですか

標本の中で値の種類が1つではなかったからです。あるレコードでは文字列、別のレコードでは数値だった、ということです。ここで頼れるタグなしのユニオンはRustにありませんし、`Value`が正直な型です。中身について嘘をつかずにデシリアライズします。

ここでの`Option<T>`と`#[serde(default)]`は何が違いますか

一部のレコードで`null`だったフィールドは`Option<T>`になります。キー自体が無かったフィールドにはさらに`#[serde(default)]`が付き、そのキーの無いレコードもエラーにならずにデシリアライズできます。標本に両方が現れていれば、両方が付きます。

文字列のフィールドからenumは作られますか

作られません。文字列はすべて`String`です。数件のレコードからenumを推論すると、標本になかったバリアントが本番で初めて届いた瞬間にデシリアライズが失敗します。緩い型よりも悪い失敗です。

他のtraitもderiveできますか

自分で追加してください。出力するderiveの一覧は意図的に`Serialize, Deserialize`だけです。`Debug`と`Clone`もほぼいつも一緒に使いますが、1行の編集で済みますし、推測を外すと、そのtraitをderiveできない型でコンパイルが通らなくなります。

ここから渡せます

次の一手

このツールが出したものをそのまま受け取れる道具です。