Ready
Ln 1, Col 1Blog

Tool Kumar tool

JSON to Rust structs

Generate public Rust structs with Debug, Clone, Serialize and Deserialize derives. JSON keys become snake_case fields with serde rename attributes when the wire name differs.

How to use this tool

  1. Paste a representative response, including records whose fields differ.
  2. Review the generated output and change the root name if needed.
  3. Copy or download the code, then check the types against your API contract.

Worked example

This output comes from the built-in converter. The two item prices infer a floating-point field; the null and string notes infer a nullable field.

Input

{
  "user-id": 42,
  "profile": {
    "city": "London",
    "created_at": "2026-10-14T09:00:00Z"
  },
  "items": [
    {
      "price": 12,
      "note": null
    },
    {
      "price": 12.5,
      "note": "gift"
    }
  ]
}

Output

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
    #[serde(rename = "user-id")]
    pub user_id: i64,
    pub profile: Profile,
    pub items: Vec<Item>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Profile {
    pub city: String,
    pub created_at: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Item {
    pub price: f64,
    pub note: Option<String>,
}

Use the structs with serde_json

Enable the derive feature on your serde dependency and add serde_json in Cargo.toml. Copy the structs into a module and deserialize the response.

Sample-based inference does not set application validation rules. Check ranges, required fields and timestamps before treating the decoded model as trusted input.

let model: Root = serde_json::from_str(&response_body)?;
let text = serde_json::to_string(&model)?;

Options and edge cases

  • Arrays become Vec and nullable typed fields become Option. Fields missing in some records add skip_serializing_if = "Option::is_none".
  • Unknown, null-only or mixed values use serde_json::Value. Renames preserve punctuation and reserved Rust words use raw identifiers when possible.
  • Integers use i64 or i128 beyond signed 64-bit. Fractions use f64. Review serde_json support and numeric range before accepting very large integers.
  • Dates remain String. Exact decimal money needs a domain type and serializer; a JSON example cannot supply those rules.

Private by default

Your document stays in this browser. Tool Kumar parses, converts and creates downloads on your device, with no account or upload step.

JSON to Rust structs questions

Does the generator include serde derives?
Yes. It imports serde::{Deserialize, Serialize} and derives Debug, Clone, Serialize and Deserialize for structs.
Are JSON names preserved?
Yes. It emits serde rename attributes where needed, and can use rename_all = "camelCase" when that reduces per-field mappings.
How are null and absent values represented?
Typed nullable or absent fields use Option<T>. Unknown and null-only fields use serde_json::Value, which can itself hold JSON null.
Can I deserialize the result with serde_json?
Yes. Add serde with its derive feature and serde_json to your Rust project, then deserialize into the generated Root type.

Related tools

JSON to Go, JSON to Java, JSON Schema generator.