JSON to Rust
Paste a JSON sample and get Rust serde structs, instantly and entirely in your browser. Optional fields, nullability and nested types are inferred from the sample — and anything the sample cannot settle is reported rather than guessed.
Type definitions will appear here
Rust serde structs from a sample
Generates #[derive(Serialize, Deserialize)] structs, with #[serde(rename)] when the Rust name differs from the JSON key.
Optional fields get Option<T> plus skip_serializing_if.
What a sample cannot tell you
Types are inferred from one sample. A field absent from your sample will be absent from the output, and a field that happens to hold only whole numbers will be typed as an integer even if it can hold decimals. Paste the widest sample you have. For a guarantee rather than an inference, start from a JSON Schema.
What Rust output looks like
Generated from two sample records, one of which has an extra field and a null. This is the actual output, not an illustration:
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
pub id: i64,
#[serde(rename = "userName")]
pub user_name: String,
#[serde(rename = "isActive")]
pub is_active: bool,
pub score: f64,
pub tags: Vec<String>,
pub address: Address,
#[serde(rename = "lastSeen")]
pub last_seen: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub nickname: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Address {
pub city: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub postcode: Option<serde_json::Value>,
}
The three things that differ by language
Large integers
Rust has i64, so large identifiers survive. serde will refuse a value that does not fit rather than truncating it, which is the behaviour you want.
Optional against nullable
Optional fields become Option<T> with #[serde(skip_serializing_if = "Option::is_none")], so a None is omitted rather than written as null.
Names that are not identifiers
#[serde(rename)] is emitted where the Rust name differs from the key, keeping snake_case idiomatic without breaking the wire format.