</>YZIF
Blog

JSON to Rust: Serde Structs Generated Instantly

2026-06-18

Why Rust + Serde?

Rust's strong type system and Serde's powerful serialization framework make an unbeatable combination for JSON handling. But manually writing struct definitions with all the Serde attributes for complex JSON can be tedious. That's where a JSON-to-Rust generator saves the day.

Real Example: Cloud Provider API Response

Here's a typical JSON response from a cloud provider's API:

{
  "server_id": "srv-a1b2c3",
  "display_name": "Production Web Server",
  "status": "running",
  "region": "us-east-1",
  "instance_type": "t3.large",
  "vcpus": 2,
  "memory_mb": 8192,
  "disk_gb": 100,
  "tags": ["production", "web", "backend"],
  "created_at": "2026-01-15T08:30:00Z",
  "ip_addresses": {
    "public": "203.0.113.42",
    "private": "10.0.1.50"
  },
  "monitoring_enabled": true,
  "backup_config": {
    "enabled": true,
    "schedule": "0 3 * * *",
    "retention_days": 30
  }
}

The generated Rust structs with Serde would be:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Server {
#[serde(rename = "server_id")]
pub server_id: String,

#[serde(rename = "display_name")]
pub display_name: String,

pub status: String,
pub region: String,

#[serde(rename = "instance_type")]
pub instance_type: String,

pub vcpus: i64,

#[serde(rename = "memory_mb")]
pub memory_mb: i64,

#[serde(rename = "disk_gb")]
pub disk_gb: i64,

pub tags: Vec,

#[serde(rename = "created_at")]
pub created_at: String,

#[serde(rename = "ip_addresses")]
pub ip_addresses: IpAddresses,

#[serde(rename = "monitoring_enabled")]
pub monitoring_enabled: bool,

#[serde(rename = "backup_config")]
pub backup_config: Option,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IpAddresses {
pub public: String,
pub private: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct BackupConfig {
pub enabled: bool,
pub schedule: String,

#[serde(rename = "retention_days")]
pub retention_days: i64,
}

Key Serde Attributes Explained

The JSON to Rust tool on YZIF intelligently applies these Serde attributes:

- **`rename`** — Maps snake_case JSON keys to Rust's field names - **`default`** — Provides default values when a field is missing in the JSON - **`skip_serializing_if`** — Omits fields from serialized output when they match a condition (e.g., `Option::is_none`) - **`deny_unknown_fields`** — Causes deserialization to fail on unknown fields (strict mode) - **`Option`** — Automatically used for nullable or optional fields

Advanced Features

Nested Option Handling
#[derive(Debug, Serialize, Deserialize)]
struct Config {
    #[serde(default)]
    pub timeout_seconds: Option,

#[serde(skip_serializing_if = "Option::is_none")]
pub fallback_url: Option,
}

Flatten for Inheritance-Like Patterns
#[derive(Debug, Serialize, Deserialize)]
struct ApiResponse {
    pub status: String,
    #[serde(flatten)]
    pub data: ExtraData,
}

Try the JSON to Rust Generator

Visit the JSON to Rust tool on YZIF to instantly generate Serde-powered Rust structs from any JSON. Just paste and copy — no manual typing needed.