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.

Basics

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: addressAddress, shipping_infoShippingInfo. 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.

Try It — JSON to Rust Struct Converter

Open full tool