What this tool does
A JSON sample becomes Rust structs with serde derives.
{ "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 field names are snake_case, so firstName becomes first_name — and #[serde(rename)] keeps the key, because a struct that no longer reads its own JSON would be worse than an unidiomatic name. The rename appears only where the two differ.
If you only ever read the payload, the option that drops Serialize gives you #[derive(Debug, Deserialize)] and one less trait to satisfy.
Keywords, raw or suffixed
{ "type": "user", "self": "/users/1" }
pub r#type: String,
#[serde(rename = "self")]
pub self_: String,
r#type is a raw identifier: serde already serialises it as type, so no attribute is needed. self is one of the few words Rust does not allow even as a raw identifier — self, Self, crate, super — so it takes an underscore and a rename instead.
What comes from serde_json
null, unknown values, empty arrays and mixed arrays all end up as serde_json::Value:
pub nickname: Option<serde_json::Value>,
pub tags: Vec<serde_json::Value>,
so serde_json belongs in your Cargo.toml alongside serde with its derive feature. The path is written in full rather than imported, which keeps the output valid whatever your module layout.
What one sample cannot say
Only null produces an Option. Everything else is required, because the document had a value — and “sometimes missing” is not something one document can show. Wrapping a field in Option<T> is one edit; #[serde(default)] is the other, when absence should mean the default rather than an error.
Two keys that snake_case to the same name — fooBar and foo_bar — are suffixed rather than merged, and each keeps its own rename.
Private by design
Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.