JSON to Rust Structs
Generates serde-annotated Rust structs from a JSON sample, with Option for nullable or missing fields and snake_case renames.
Emits Rust structs with `serde` derives from a sample JSON document — `Serialize`, `Deserialize`, the right `Option<…>` on fields that were sometimes absent, and a `#[serde(rename = "…")]` wherever the JSON key is not a legal snake_case field name.
Sample JSON
Drop a .json file
Read in this tab. Nothing is uploaded.
Give it every element you have. Every extra record narrows the guess — a field missing from one of them is what makes it optional.
Rust
How to use it
Paste as many records as you have
Every element of every array is read and merged, not just the first. Three records tell it far more than one, because a field missing from one of them is exactly what makes that field optional.
Name the root type
Nested objects are named after the key that holds them, singularised for arrays, so `users` yields a `User`. Only the root needs a name from you.
Read the counts under the output
Types, optional fields, unions and how many records were merged. A union count above zero means a field held two different kinds of value across your sample — worth looking at before you paste the result into a codebase.
Paste the structs into your crate
The `use serde::{Deserialize, Serialize};` line is emitted for you; the crate itself and its `derive` feature are yours to add to Cargo.toml.
Common questions
Why did a field come out as `serde_json::Value`?
Because it held more than one kind of value across the sample — a string in one record and a number in another. Rust has no untagged union to fall back on here, and `Value` is the honest type: it deserialises without lying about what is inside.
What is the difference between `Option<T>` and `#[serde(default)]` here?
A field that was `null` in some records becomes `Option<T>`; a field that was simply absent also gets `#[serde(default)]`, so deserialising a record without it succeeds instead of erroring. Both appear together when the sample showed both.
Are enums generated for string fields?
No. Every string is `String`. Inferring an enum from a handful of records means a deserialise error the first time production sends a variant your sample did not contain, which is a worse failure than a loose type.
Can I derive other traits?
Add them yourself — the emitted derive list is deliberately just `Serialize, Deserialize`. `Debug` and `Clone` are almost always wanted too, but they are a one-line edit and guessing wrong makes the output not compile for types that cannot derive them.
Feed it from
JSON to Go Structs
Generates Go structs with json tags from a JSON sample, including nested and repeated types.
JSON Formatter & Validator
Pretty-prints, minifies and validates JSON, pointing at the exact line and column of a syntax error.
YAML Formatter & Validator
Re-indents YAML consistently, validates it, and flags the tab and anchor mistakes that break parsers.
TOML Formatter & Validator
Formats and validates TOML, normalising table ordering and inline-table style.
Next
These accept what this tool produces, so the result can go straight in.
JSON Formatter & Validator
Pretty-prints, minifies and validates JSON, pointing at the exact line and column of a syntax error.
JSON to Go Structs
Generates Go structs with json tags from a JSON sample, including nested and repeated types.
JSON to TypeScript
Infers TypeScript interfaces or types from a JSON sample, merging optional and union fields.
Base64 Encoder & Decoder
Encodes and decodes Base64 and Base64URL for text or files, handling UTF-8 correctly.
curl to Code
Converts a curl command into fetch, axios, Python requests, Go, PHP or PowerShell.
Text Hash
Computes MD5, SHA-1, SHA-256, SHA-384, SHA-512 and CRC-32 of a string, with an uppercase and Base64 output option.