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

如何从String类型获取Prost!生成的枚举实例

从字符串解析Prost生成的枚举实例

方案1:直接用Prost自带API

Prost的Enumeration trait已经内置了字符串转枚举的方法,不需要额外依赖。直接调用from_str_name即可:

use your_crate::Fruit;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let fruit = Fruit::from_str_name("APPLE")?;
    assert_eq!(fruit, Fruit::Apple);
    Ok(())
}

该方法返回Result<Self, prost::DecodeError>,仅匹配枚举as_str_name()返回的全大写字符串。

方案2:通过build.rs+include!扩展枚举

如果需要支持大小写不敏感解析或自定义逻辑,可以用构建脚本生成带strum注解的枚举包装代码:

  1. 编写build.rs生成带strum派生的枚举代码:
use std::fs::write;
use std::path::Path;

fn main() {
    let enum_code = r#"
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration, strum::EnumString)]
#[strum(ascii_case_insensitive)]
#[repr(i32)]
pub enum Fruit {
    Unspecified = 0,
    Apple = 1,
    Banana = 2,
    Lemon = 3,
}
"#;
    let out_dir = std::env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("fruit_enum.rs");
    write(dest_path, enum_code).unwrap();
}
  1. 在源码中引入生成的代码:
include!(concat!(env!("OUT_DIR"), "/fruit_enum.rs"));

fn main() {
    let fruit = Fruit::from_str("apple").unwrap();
    assert_eq!(fruit, Fruit::Apple);
}

注意:需保证生成的枚举结构与Prost自动生成的完全一致,避免版本更新后出现不匹配。

方案3:手动实现解析逻辑

如果枚举成员不多,也可以直接手写匹配逻辑,无需额外依赖:

impl Fruit {
    pub fn from_str(s: &str) -> Option<Self> {
        match s.to_ascii_uppercase().as_str() {
            "UNSPECIFIED" => Some(Fruit::Unspecified),
            "APPLE" => Some(Fruit::Apple),
            "BANANA" => Some(Fruit::Banana),
            "LEMON" => Some(Fruit::Lemon),
            _ => None,
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:00:53