JSON to Rust Struct
Generate nested Rust structs with Serde derives, rename attributes, Vec, and Option fields
Optional fields are inferred from missing and null values across object samples. Mixed types fall back to a generic type; review the result against the real API contract.
Generated Rust structs will appear here.
About this tool
JSON to Rust Struct infers a family of Rust structs from a JSON object or representative object array. Strings, booleans, integers, decimals, arrays, and nested objects map to String, bool, i64, f64, Vec, and named models; incompatible mixed samples fall back to serde_json::Value. Missing or null properties become Option fields. Optional Serde derives and rename/default attributes preserve wire keys and deserialization behavior, while a visibility switch controls pub fields. The generator sanitizes snake_case identifiers and uses raw identifiers for Rust keywords. It cannot infer chrono types, enums, lifetimes, borrowing, custom deserializers, numeric bounds, or domain invariants, so run rustfmt and compile against representative fixtures.
Scenario Recipes
Draft Serde models for an external API
Goal: Preserve JSON wire keys and nullable behavior before implementing client logic
- Paste multiple representative objects so missing fields and mixed samples are visible.
- Enable Serde derives, choose field visibility, and generate a domain-specific root model.
- Replace generic values with enums or chrono types, add crate imports, run rustfmt, and deserialize fixtures in tests.
Result: A nested Rust model draft with explicit Option and Serde mappings.
Frequently Asked Questions
How are missing and null fields represented?
They become Option<T>; with Serde enabled, optional fields also receive default handling.
What happens when sample values use incompatible types?
The field falls back to serde_json::Value instead of guessing an unsafe concrete type.
Are JSON property names converted to snake_case?
Yes. Serde rename attributes preserve the exact source name when normalization changes it.
How are Rust keywords handled?
Field names such as type are emitted as raw identifiers like r#type.
Does it infer chrono dates or enums?
No. Strings and repeated values lack enough domain information; adjust them after contract review.
Is the JSON uploaded?
No. Parsing, multi-sample inference, naming, and Rust generation run locally.
Keep browsing