You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Serde枚举实现JSON可选字段的反序列化?(Rust)

用Serde简便实现枚举与JSON字符串的映射

示例JSON

假设你有如下结构的JSON数据:

{
  "state": "open",
  "name": "Project Alpha"
}

简便实现方案

不需要写自定义反序列化逻辑,借助Serde的derive宏和属性注解就能直接完成映射,有两种常见方式:

方式1:统一命名转换

如果枚举变体名称(如Open、Closed)和JSON中的字符串值(open、closed)是驼峰转蛇形小写的对应关系,直接用rename_all属性统一处理:

use serde::Deserialize;
use serde_json;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
enum State {
    Open,
    Closed,
}

#[derive(Debug, Deserialize)]
struct Project {
    state: State,
    name: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_str = r#"{"state": "closed", "name": "Project Beta"}"#;
    let project: Project = serde_json::from_str(json_str)?;
    println!("反序列化结果: {:?}", project);
    Ok(())
}

方式2:单独指定变体映射

如果枚举变体名称和JSON值没有统一的命名规律,可以给每个变体单独加rename属性指定对应的JSON字符串:

use serde::Deserialize;
use serde_json;

#[derive(Debug, Deserialize)]
enum State {
    #[serde(rename = "open")]
    Active,
    #[serde(rename = "closed")]
    Archived,
}

#[derive(Debug, Deserialize)]
struct Project {
    state: State,
    name: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json_str = r#"{"state": "open", "name": "Project Gamma"}"#;
    let project: Project = serde_json::from_str(json_str)?;
    println!("反序列化结果: {:?}", project);
    Ok(())
}

说明

这两种方式都是利用Serde内置的derive扩展能力,不需要手动实现Deserialize trait的逻辑,完全满足你将open映射到State::Open、closed映射到State::Closed的需求,比自定义反序列化简洁得多。

内容的提问来源于stack exchange,提问作者rednaks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:00:46