如何从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注解的枚举包装代码:
- 编写
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(); }
- 在源码中引入生成的代码:
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
相关产品推荐
相关产品推荐

