Skip to content
AZ Tools

JSON to Rust Struct Converter (serde)

Turn a JSON object into Rust structs with serde derives and type-mapped fields, in your browser.

Rust structs

How to use

  1. Paste or type your JSON into the input box.
  2. Optionally rename the root struct (defaults to AutoGenerated).
  3. Copy the generated structs from the output box and add serde to your Cargo.toml.

About this tool

Show

Paste any JSON object or array and get Rust struct definitions deriving Serialize and Deserialize from serde, with a separate struct for every nested object. Whole numbers map to i64 and fractional ones to f64, and a key that is not already snake_case is renamed in Rust while a serde rename attribute preserves the original spelling on the wire — so camelCase JSON deserialises into idiomatic Rust without you touching it. Where the sample cannot decide a type, serde_json::Value is used: that covers a null and an empty array. The one thing to add yourself is optionality — every field is generated as required, so wrap the ones your API may omit in Option and give them serde's default. Everything runs locally in your browser.

Frequently asked questions

How are numbers typed?

Whole numbers become i64 and numbers with a decimal point become f64. Adjust manually if you need u32, i32 or another width.

What happens with null or empty arrays?

null values map to Option<serde_json::Value> and empty arrays to Vec<serde_json::Value>, since their type can't be inferred from the sample.

Why do some fields have a serde rename?

Rust fields use snake_case. When a JSON key differs (for example camelCase), a #[serde(rename = "...")] attribute is added so serialization still matches the original key.

Is my JSON sent anywhere?

No. Conversion happens entirely in your browser; nothing is uploaded.

How do I make a field optional?

Wrap the type in Option and add #[serde(default)]. Option alone lets the key be null; the default attribute lets it be absent entirely. Without both, deserialization fails the moment the server stops sending a field it used to send, which a sample can never warn you about.

Why not use u64 for ids that are never negative?

You can, and it documents intent. The reason the default is i64 is that a sample cannot prove a value never goes negative, and an unsigned type turns a single unexpected -1 into a hard deserialization error rather than a value you can inspect and handle.

Related tools