如何用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
相关产品推荐
相关产品推荐

