Rust中如何将JSON字符串反序列化为指定枚举类型?
将字符串转换为指定Rust枚举变体的方案
你的枚举定义对应各字符串的中文含义如下:
"040000"→SubdirectoryTree(子目录树)"100644"→FileBlob(普通文件Blob)"100755"→ExecutableBlob(可执行文件Blob)"120000"→SymlinkPathBlob(符号链接路径Blob)"160000"→SubmoduleCommit(子模块提交)""→Noop(无操作)- 其他未匹配字符串 →
FallthroughString(兜底变体)
方法1:借助serde反序列化
由于枚举已派生Deserialize trait,直接用serde的反序列化能力就能完成转换,无需额外编写匹配逻辑:
use serde::Deserialize; use serde_json; #[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)] pub enum GitCreateTreeRequestMode { #[serde(rename = "040000")] SubdirectoryTree, #[serde(rename = "100644")] FileBlob, #[serde(rename = "100755")] ExecutableBlob, #[serde(rename = "120000")] SymlinkPathBlob, #[serde(rename = "160000")] SubmoduleCommit, #[serde(rename = "")] Noop, #[serde(other)] FallthroughString, } fn main() -> Result<(), Box<dyn std::error::Error>> { let mode_str = "040000"; // 将字符串包装为JSON格式后反序列化 let mode: GitCreateTreeRequestMode = serde_json::from_str(&format!("\"{}\"", mode_str))?; assert_eq!(mode, GitCreateTreeRequestMode::SubdirectoryTree); println!("转换结果: {:?}", mode); Ok(()) }
方法2:手动实现字符串匹配
如果不想依赖serde的反序列化流程,可以给枚举添加一个静态方法,手动匹配字符串:
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)] pub enum GitCreateTreeRequestMode { #[serde(rename = "040000")] SubdirectoryTree, #[serde(rename = "100644")] FileBlob, #[serde(rename = "100755")] ExecutableBlob, #[serde(rename = "120000")] SymlinkPathBlob, #[serde(rename = "160000")] SubmoduleCommit, #[serde(rename = "")] Noop, #[serde(other)] FallthroughString, } impl GitCreateTreeRequestMode { pub fn from_str(s: &str) -> Self { match s { "040000" => Self::SubdirectoryTree, "100644" => Self::FileBlob, "100755" => Self::ExecutableBlob, "120000" => Self::SymlinkPathBlob, "160000" => Self::SubmoduleCommit, "" => Self::Noop, _ => Self::FallthroughString, } } } fn main() { let mode_str = "040000"; let mode = GitCreateTreeRequestMode::from_str(mode_str); assert_eq!(mode, GitCreateTreeRequestMode::SubdirectoryTree); println!("转换结果: {:?}", mode); }
两种方法对比
- 方法1:复用serde现有实现,无需手动维护匹配逻辑,适合已使用serde的项目,但需要处理JSON格式的包装(给字符串加引号)。
- 方法2:逻辑直观,不依赖额外反序列化流程,适合简单场景,但枚举的
rename值变更时,需要同步更新匹配分支。
内容的提问来源于stack exchange,提问作者FreePhoenix888
相关产品推荐
相关产品推荐

