Rust Enum from a String Union Field

Replace a String field with a typed Rust enum when JSON values come from a fixed set. Compile-time exhaustiveness without giving up serde compatibility.

Type Mapping

Detailed Explanation

Promoting a String Field to a serde-Aware Enum

When a JSON field always holds one of a fixed set of strings ("active", "inactive", "banned"), you can replace the generated String field with a Rust enum. The compiler then forces every match arm to be handled.

Example JSON

{
  "id": 1,
  "name": "Ada",
  "status": "active"
}

Generated Rust (initial)

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
    pub id: i32,
    pub name: String,
    pub status: String,
}

Promoted to an enum

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Status {
    Active,
    Inactive,
    Banned,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Root {
    pub id: i32,
    pub name: String,
    pub status: Status,
}

Why rename_all

Without #[serde(rename_all = "lowercase")], serde would expect the JSON to send "Active" (matching the variant name). Most APIs use lowercase or snake_case, so rename_all keeps the JSON contract intact while letting your Rust code use idiomatic PascalCase variants.

Other rename strategies

Attribute JSON form
"lowercase" active
"UPPERCASE" ACTIVE
"snake_case" active_user
"SCREAMING_SNAKE_CASE" ACTIVE_USER
"kebab-case" active-user

Variant aliases

If the API sends multiple spellings for the same logical value, use per-variant rename:

pub enum Role {
    #[serde(rename = "admin")]
    Administrator,
    #[serde(rename = "user", alias = "regular")]
    Regular,
}

Catching unknown values

Add a fallback variant to gracefully handle new server-side values:

#[serde(other)]
Unknown,

This prevents your client from crashing when the API adds a new status next quarter.

Use Case

Order states, user roles, payment statuses, and event types are all natural enums. Rust's exhaustive match plus serde's rename attributes give you compile-time safety with zero runtime overhead.

Try It — JSON to Rust Struct Converter

Open full tool