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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 14:48:24