Nested Rust Struct from Hierarchical JSON
Map a JSON object with one level of nesting onto two Rust structs. Learn how the converter names child structs from parent fields.
Detailed Explanation
Splitting Nested JSON into Multiple Structs
Rust does not allow anonymous inline structs the way TypeScript does. Each nested JSON object becomes its own named struct, and the parent struct holds a typed field referring to it.
Example JSON
{
"user": {
"name": "Bob",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Springfield",
"zip": "62704"
}
}
}
Generated Rust
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
pub user: User,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub name: String,
pub age: i32,
pub address: Address,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Address {
pub street: String,
pub city: String,
pub zip: String,
}
How the names are picked
The struct name comes from the parent field, transformed to PascalCase: address → Address, shipping_info → ShippingInfo. If two different objects normalize to the same name, the converter appends a numeric suffix (Address, Address2) so the file still compiles.
Why this matters
Splitting nested objects into named types makes them reusable. You can write a function like fn validate(addr: &Address) -> bool and call it for any Address value regardless of where it came from. Anonymous inline types would force you to repeat the field list at every call site.
Module organization tip
For very large APIs, move each generated struct into its own file under a models module and re-export them from mod.rs. The compiler does not care, but humans reading the code do.
Use Case
Most external APIs (Stripe, GitHub, Slack) return responses with two or three levels of nested objects. Generating the full hierarchy in one paste avoids hours of typing and prevents typos in field names.