TXT · Text & Data tools

JSON to Rust Struct Converter

Top-level type
Visibility
Integers
Density
JSON input
Rust (serde) output
Inference
Rust (serde)languageJSON sampleinput0types0lines out0chars out
Go to the full JSON to Types generator with all ten languages

Shareable link

Settings are written to the URL as you change them. Nothing differs from the defaults yet.

Rust structs from a JSON sample

Paste a JSON document and get structs annotated for serde. Each object shape becomes a struct, each repeated string set becomes an enum, and every type carries #[derive(Serialize, Deserialize)] plus the traits you select.

Example

{ "id": 7, "email": null, "orders": [{ "sku": "X1", "qty": 2 }, { "sku": "X2", "qty": 1, "gift": true }] }
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Customer {
    pub id: i64,
    pub email: Option<serde_json::Value>,
    pub orders: Vec<Order>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Order {
    pub sku: String,
    pub qty: i64,
    pub gift: Option<bool>,
}

email is Option<serde_json::Value> because the sample shows only null, so nothing narrower can be claimed. A second sample with a string there would produce Option<String>.

Derives and density

derive Debug and derive Clone are on by default; derive PartialEq is off because floating-point fields make equality a judgement call. Dense removes the blank line between fields. Usage comment controls the commented example at the top that shows how to call serde_json::from_str.

Limits

A field that mixes incompatible types across the sample becomes an untagged enum with one variant per type, which serde deserializes by trying each in order. Dates become String unless date inference is on, in which case they still render as String: the Rust renderer does not pull in chrono, so parse them yourself after decoding.

Frequently Asked Questions

serde with the derive feature, and serde_json for the usage shown in the leading comment. The structs derive Serialize and Deserialize; nothing else is required.

A key missing from some objects becomes Option<T>, which serde reads as None when the key is absent or null. Check skip_serializing_if None to leave None fields out when serializing.

Smallest that fits picks i64 for whole numbers and f64 for fractions. Always i32 or Always i64 force one width for every integer field.

Fields are renamed to snake_case to satisfy rustc's naming lints. When the generated name differs from the key, a #[serde(rename = "key")] attribute keeps the wire name.

Yes. Visibility offers pub, pub(crate), and private. Private fields need constructors or accessors of your own; the derives still work.

Generate types for one language

Full JSON to Types Generator tool

Explore Our Tools

Browse all tools