このツールの動作
JSON の標本が、serde の派生付き Rust 構造体になります。
{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
pub id: i64,
#[serde(rename = "firstName")]
pub first_name: String,
pub address: Address,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
pub city: String,
}
Rust の項目名は snake_case なので、firstName は first_name になります。そして #[serde(rename)] が鍵を保ちます。自分の JSON を読めなくなった構造体のほうが、流儀に外れた名前より悪いからです。rename は、二つが食い違うところにだけ現れます。
荷を読むだけなら、Serialize を外す選択肢があります。#[derive(Debug, Deserialize)] になり、満たすべき trait が一つ減ります。
予約語は、生のままか、下線付きか
{ "type": "user", "self": "/users/1" }
pub r#type: String,
#[serde(rename = "self")]
pub self_: String,
r#type は生識別子です。serde はすでにこれを type として直列化するので、属性は要りません。self は、Rust が生識別子としてすら認めない数少ない語の一つです——self、Self、crate、super——なので、下線と rename を受け取ります。
serde_json から来るもの
null、型の分からない値、空の配列、型の混ざった配列は、いずれも serde_json::Value になります。
pub nickname: Option<serde_json::Value>,
pub tags: Vec<serde_json::Value>,
ですから serde_json は、derive 機能付きの serde と並んで Cargo.toml に入ります。経路は取り込まずに丸ごと書いてあるので、あなたのモジュール構成がどうであれ、出力は妥当なままです。
標本が言えないこと
Option になるのは null だけです。ほかはすべて必須です。文書に値があったからで、「ときどき無い」は文書ひとつが示せることではありません。項目を Option<T> で包むのが一つの手入れ、#[serde(default)] がもう一つです。無いことを誤りではなく既定値として扱いたいときに使います。
同じ snake_case になる二つの鍵——fooBar と foo_bar——は、混ぜずに接尾辞で分け、それぞれが自分の rename を保ちます。
プライバシー
すべての処理はブラウザ内のJavaScriptだけで完結します。データがアップロードされることはないため、機密情報でも安心して利用でき、オフラインでも動作します。