Skip to content
UniKit

JSON to Rust

Generate Rust structs with serde derives from a JSON sample: Option fields, Vec types, serde rename attributes and four naming conventions.

Runs in your browserEvery computation happens in your browser — your data never leaves this device.

Options
Generated Rust
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RootOwner {
    pub name: String,
    pub email: serde_json::Value,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RootItems {
    pub sku: String,
    pub price: f64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub note: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    pub name: String,
    pub is_active: bool,
    pub score: f64,
    pub owner: RootOwner,
    pub tags: Vec<String>,
    pub items: Vec<RootItems>,
    pub meta: serde_json::Value,
}

Summary: Types 3 · Fields 13 · Name clashes 0

What this tool does

  • Turn a third-party API response into structs with serde derives, so reqwest plus serde_json can deserialize it without hand-written boilerplate.
  • Handle nullable data: null values and keys missing from some array elements become Option<T>, and optional fields also get skip_serializing_if so no stray nulls are written back.
  • Camel-case JSON keys with snake_case Rust fields get #[serde(rename = "...")] automatically, instead of you writing rename attributes by hand.
  • Keys that clash with Rust keywords (type, match, loop, …) get an underscore appended, so the generated code compiles as-is.

Example

Input

{"id":1,"name":"UniKit","tags":["a","b"]}

Output

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    pub name: String,
    pub tags: Vec<String>,
}

Numbers map to i64 / f64, strings to String and arrays to Vec<T>; heterogeneous arrays and null fields use serde_json::Value, which needs the serde_json dependency.

Frequently asked questions

Why is a string field String instead of &str?

The generated struct must own its data after deserialization, while &str needs lifetime parameters and can only borrow. For zero-copy parsing, change the field to Cow<str> or &str and add the lifetime yourself.

When does serde_json::Value show up?

When a value is null, when an array mixes element types (say [1, "a"]), or when an empty array gives no element type to infer. Those fields become serde_json::Value, so remember to add the serde_json dependency to Cargo.toml.

Is serde rename really necessary?

Yes whenever the field name differs from the JSON key, otherwise deserialization finds no matching key and the field stays at its default. It is on by default, and fields whose names already match generate no attribute.

What does skip_serializing_if do?

For optional fields (keys present in only some array elements), a None value means the key is omitted entirely when serializing back to JSON, instead of emitting nulls. If you only deserialize, you can delete the line.

Is my JSON uploaded anywhere?

No. Parsing and code generation run locally in your browser with no network requests, and it works offline.

Keywords:jsonruststructserdeoptionjson to rustJSON 转 Rust结构体序列化代码生成

Related tools