Rust枚举与字符串转换库sea-strum的使用,高效实现枚举与字符串间的双向转换
Rust枚举与字符串转换库strum的使用,高效实现枚举与字符串间的双向转换
Strum是一组用于在Rust中更轻松处理枚举和字符串的宏和特性集合。
兼容性
Strum目前支持Rust版本>=1.32.0。该项目目标是支持至少2年的Rust版本。
在项目中包含Strum
在Cargo.toml中添加以下依赖:
[dependencies]
strum = "0.23"
strum_macros = "0.23"
# 也可以使用"derive"特性,直接从"strum"导入宏
# strum = { version = "0.23", features = ["derive"] }
Strum宏
Strum实现了以下宏:
宏 | 描述 |
---|---|
EnumString | 根据名称将字符串转换为枚举变体 |
Display | 将枚举变体转换为字符串 |
FromRepr | 从整数转换为枚举 |
AsRefStr | 为MyEnum实现AsRef<str> |
IntoStaticStr | 为枚举实现From<MyEnum> for &'static str |
EnumVariantNames | 添加关联的VARIANTS 常量,是判别名称的数组 |
EnumIter | 创建迭代枚举变体的新类型 |
EnumProperty | 向枚举变体添加自定义属性 |
EnumMessage | 向枚举变体添加详细消息 |
EnumDiscriminants | 生成仅包含判别名称的新类型 |
EnumCount | 添加等于变体数量的常量usize |
完整示例代码
以下是一个完整的示例,展示如何使用strum实现枚举与字符串的双向转换:
use strum_macros::{Display, EnumString};
#[derive(Debug, Display, EnumString, PartialEq)]
enum Color {
#[strum(serialize = "red", serialize = "r")]
Red,
#[strum(serialize = "green", serialize = "g")]
Green,
#[strum(serialize = "blue", serialize = "b")]
Blue,
}
fn main() {
// 枚举转字符串
let red_str = Color::Red.to_string();
println!("Red as string: {}", red_str); // 输出: red
// 字符串转枚举
let color: Color = "green".parse().unwrap();
assert_eq!(color, Color::Green);
// 使用替代名称
let color: Color = "b".parse().unwrap();
assert_eq!(color, Color::Blue);
}
这个示例展示了:
- 使用
Display
特性将枚举转换为字符串 - 使用
EnumString
特性将字符串解析为枚举 - 为每个枚举变体定义多个字符串表示形式
扩展示例代码
// 导入需要的宏
use strum_macros::{Display, EnumString, EnumIter, EnumCount};
#[derive(Debug, Display, EnumString, EnumIter, EnumCount, PartialEq)]
enum HttpStatus {
#[strum(serialize = "200 OK", serialize = "ok")]
Ok,
#[strum(serialize = "404 Not Found")]
NotFound,
#[strum(serialize = "500 Internal Server Error")]
InternalServerError,
}
fn main() {
// 1. 枚举转字符串
println!("Status: {}", HttpStatus::Ok); // 输出: 200 OK
// 2. 字符串转枚举
let status: HttpStatus = "404 Not Found".parse().unwrap();
assert_eq!(status, HttpStatus::NotFound);
// 3. 使用EnumIter迭代所有变体
println!("\nAll HTTP status variants:");
for variant in HttpStatus::iter() {
println!("- {:?}", variant);
}
// 4. 使用EnumCount获取变体数量
println!("\nTotal variants: {}", HttpStatus::COUNT);
// 5. 使用替代名称解析
let status: HttpStatus = "ok".parse().unwrap();
assert_eq!(status, HttpStatus::Ok);
}
调试
要查看生成的代码,可以在编译前设置STRUM_DEBUG环境变量:
STRUM_DEBUG=1
将显示所有类型的生成代码STRUM_DEBUG=YourType
将仅显示特定类型的生成代码
名称由来
Strum是STRING enUM的缩写,因为它是一个通过字符串增强枚举信息的库。Strumming也是一种非常随意的动作,很像编写Rust代码。
1 回复
Rust枚举与字符串转换库strum
的使用指南
strum
是一个强大的Rust库,专门用于简化枚举(enum)与字符串之间的双向转换操作。它通过过程宏提供了一系列特性,可以高效地实现枚举值与字符串表示之间的相互转换。
主要特性
- 自动实现
ToString
/FromStr
trait - 支持枚举变体到字符串的各种命名风格转换
- 支持枚举的序列化/反序列化
- 提供枚举变体的迭代功能
基本用法
首先在Cargo.toml
中添加依赖:
[dependencies]
strum = "0.25"
strum_macros = "0.25"
示例1:基本字符串转换
use strum_macros::{Display, EnumString};
#[derive(Debug, Display, EnumString, PartialEq)]
enum Color {
Red,
Blue,
Green,
#[strum(serialize = "Yellow", serialize = "Golden")]
Yellow,
}
fn main() {
// 枚举转字符串
assert_eq!("Red", Color::Red.to_string());
assert_eq!("Yellow", Color::Yellow.to_string());
// 字符串转枚举
assert_eq!(Color::Red, "Red".parse().unwrap());
assert_eq!(Color::Yellow, "Golden".parse().unwrap());
}
示例2:自定义字符串表示
use strum_macros::{Display, EnumString};
#[derive(Debug, Display, EnumString)]
enum HttpStatus {
#[strum(serialize = "200 OK")]
Ok,
#[strum(serialize = "404 Not Found")]
NotFound,
#[strum(serialize = "500 Internal Server Error")]
InternalServerError,
}
fn main() {
println!("{}", HttpStatus::Ok); // 输出 "200 OK"
let status: HttpStatus = "404 Not Found".parse().unwrap();
println!("{:?}", status); // 输出 "NotFound"
}
示例3:自动命名风格转换
use strum_macros::{Display, EnumString};
#[derive(Debug, Display, EnumString)]
#[strum(serialize_all = "snake_case")]
enum ProgrammingLanguage {
Rust,
JavaScript,
TypeScript,
CPlusPlus,
}
fn main() {
assert_eq!("rust", ProgrammingLanguage::Rust.to_string());
assert_eq!(ProgrammingLanguage::JavaScript, "javascript".parse().unwrap());
}
高级用法
枚举变体迭代
use strum_macros::{Display, EnumIter};
use strum::IntoEnumIterator;
#[derive(Debug, Display, EnumIter)]
enum Direction {
North,
South,
East,
West,
}
fn main() {
for direction in Direction::iter() {
println!("{}", direction);
}
}
配合Serde使用
use strum_macros::{Display, EnumString, Serialize, Deserialize};
use serde::{Serialize, Deserialize};
#[derive(Debug, Display, EnumString, Serialize, Deserialize)]
enum Fruit {
Apple,
Banana,
Orange,
}
fn main() {
let fruit = Fruit::Apple;
let json = serde_json::to_string(&fruit).unwrap();
println!("{}", json); // 输出 ""Apple""
let fruit: Fruit = serde_json::from_str("\"Banana\"").unwrap();
assert_eq!(fruit, Fruit::Banana);
}
常见宏说明
Display
- 自动派生ToString
traitEnumString
- 自动派生FromStr
traitEnumIter
- 为枚举提供迭代功能IntoStaticStr
- 将枚举转换为&'static str
EnumVariantNames
- 获取所有变体名称的数组
完整示例代码
下面是一个整合了strum
主要功能的完整示例:
// 引入必要的宏和trait
use strum_macros::{Display, EnumString, EnumIter, EnumVariantNames};
use strum::IntoEnumIterator;
use serde::{Serialize, Deserialize};
// 定义一个使用多种strum特性的枚举
#[derive(Debug, Display, EnumString, EnumIter, EnumVariantNames, PartialEq, Serialize, Deserialize)]
#[strum(serialize_all = "kebab-case")]
enum Animal {
#[strum(serialize = "Dog", serialize = "Canine")]
Dog,
Cat,
#[strum(serialize = "Elephant", serialize = "BigAnimal")]
Elephant,
#[strum(disabled)]
HiddenAnimal,
}
fn main() {
// 1. 测试Display特性 - 枚举转字符串
println!("\n--- 枚举转字符串 ---");
println!("Dog: {}", Animal::Dog.to_string()); // 输出 "dog"
println!("Elephant: {}", Animal::Elephant.to_string()); // 输出 "elephant"
// 2. 测试EnumString特性 - 字符串转枚举
println!("\n--- 字符串转枚举 ---");
let dog: Animal = "Dog".parse().unwrap();
println!("解析Dog: {:?}", dog);
let elephant: Animal = "BigAnimal".parse().unwrap();
println!("解析BigAnimal: {:?}", elephant);
// 3. 测试EnumIter特性 - 枚举迭代
println!("\n--- 枚举迭代 ---");
for animal in Animal::iter() {
println!("迭代: {}", animal);
}
// 4. 测试EnumVariantNames特性 - 获取所有变体名称
println!("\n--- 枚举变体名称 ---");
println!("所有变体: {:?}", Animal::VARIANTS);
// 5. 测试与Serde的集成
println!("\n--- Serde序列化/反序列化 ---");
let animal = Animal::Cat;
let json = serde_json::to_string(&animal).unwrap();
println!("序列化: {}", json);
let animal: Animal = serde_json::from_str("\"elephant\"").unwrap();
println!("反序列化: {:?}", animal);
}
这个完整示例展示了strum
库的核心功能:
- 枚举与字符串之间的双向转换
- 多种字符串表示形式支持
- 枚举迭代功能
- 获取枚举变体名称
- 与Serde的集成使用
strum
库极大地简化了Rust中枚举与字符串之间的转换工作,是处理这类需求的理想选择。