8 个不稳定版本 (3 个破坏性更新)
0.4.0 | 2023年11月19日 |
---|---|
0.3.1 | 2023年10月2日 |
0.3.0 | 2023年7月27日 |
0.2.1 | 2023年2月8日 |
0.1.1 | 2021年5月22日 |
#494 in 编码
每月下载量625
46KB
421 行
enumscribe
该软件包提供了在简单枚举和字符串之间转换的 derive 宏。它还包括为简单枚举提供 serde::Serialize
和 serde::Deserialize
derive 宏。
将 enumscribe 添加到您的项目中
添加到您的 Cargo.toml 文件中
[dependencies]
enumscribe = "0.4"
derive 宏和 serde
支持默认启用。可以通过设置 default-features = false
来禁用。
您还可以单独使用 enumscribe_derive
软件包,而不使用 enumscribe
软件包。但是,这样做意味着您只能使用 derive serde::Serialize
和 serde::Deserialize
。
用法
您可以从多种不同的 traits 中选择 derive。 "Scribe" traits 用于将枚举转换为字符串,而 "Unscribe" traits 用于将字符串转换为枚举。
基本用法
use enumscribe::{ScribeStaticStr, TryUnscribe};
#[derive(ScribeStaticStr, TryUnscribe, PartialEq, Eq, Debug)]
enum Airport {
#[enumscribe(str = "LHR")]
Heathrow,
#[enumscribe(str = "LGW")]
Gatwick,
#[enumscribe(str = "LTN")]
Luton,
}
// Convert an Airport to a &'static str
assert_eq!(Airport::Heathrow.scribe(), "LHR");
// Convert a &str to a Option<Airport>
assert_eq!(Airport::try_unscribe("LGW"), Some(Airport::Gatwick));
使用 #[enumscribe(str = "...")]
可以指定用于表示特定变体的字符串。如果省略,则使用变体名称。
不区分大小写
使用 #[enumscribe(case_insensitive)]
属性可以使 "Unscribe" traits 对变体执行不区分大小写的匹配
use enumscribe::TryUnscribe;
#[derive(TryUnscribe, PartialEq, Eq, Debug)]
enum Website {
#[enumscribe(str = "github.com", case_insensitive)]
Github,
#[enumscribe(str = "crates.io", case_insensitive)]
CratesDotIo,
}
assert_eq!(Website::try_unscribe("GiThUb.CoM"), Some(Website::Github));
相同的属性也可以用在枚举本身上,使所有变体不区分大小写。单独的字段可以选择使用#[enumscribe(case_sensitive)]
来恢复大小写敏感。
use enumscribe::TryUnscribe;
#[derive(TryUnscribe, PartialEq, Eq, Debug)]
#[enumscribe(case_insensitive)]
enum Website {
#[enumscribe(str = "github.com")]
Github,
#[enumscribe(str = "crates.io")]
CratesDotIo,
}
assert_eq!(Website::try_unscribe("CrAtEs.Io"), Some(Website::CratesDotIo));
"other"变体
您还可以有一个存储无法与任何其他变体匹配的字符串的变体。这是通过使用#[enumscribe(other)]
属性来完成的。该变体应有一个单独的字段,该字段是一个String
。
use std::borrow::Cow;
use enumscribe::{Unscribe, ScribeCowStr};
#[derive(ScribeCowStr, Unscribe, PartialEq, Eq, Debug)]
enum Website {
#[enumscribe(str = "github.com", case_insensitive)]
Github,
#[enumscribe(str = "crates.io", case_insensitive)]
CratesDotIo,
#[enumscribe(other)]
Other(String),
}
// Note that we don't need to use an Option anymore!
assert_eq!(Website::unscribe("github.com"), Website::Github);
// Unbelievably, websites exist other than github and crates.io
assert_eq!(Website::unscribe("stackoverflow.com"), Website::Other("stackoverflow.com".to_owned()));
// We can't scribe to a &'static str anymore, so we use a Cow<'static, str> instead
assert_eq!(Website::Github.scribe(), Cow::Borrowed::<'static, str>("github.com"));
assert_eq!(Website::Other("owasp.org".to_owned()).scribe(), Cow::Owned::<'static, str>("owasp.org".to_owned()));
忽略变体
如果您需要,可以使用#[enumscribe(ignore)]
来防止变体被Scribe或Unscribe特质使用。
但是,这意味着将枚举转换为字符串可能会失败,所以在这种情况下您必须使用TryScribe而不是Scribe。
use enumscribe::TryScribeStaticStr;
#[derive(TryScribeStaticStr, PartialEq, Eq, Debug)]
enum Airport {
#[enumscribe(str = "LHR")]
Heathrow,
#[enumscribe(str = "LGW")]
Gatwick,
#[enumscribe(str = "LTN")]
Luton,
#[enumscribe(ignore)]
SecretExtraVariant(i32), // we have to ignore this variant because of the i32 field
}
assert_eq!(Airport::SecretExtraVariant(123).try_scribe(), None);
assert_eq!(Airport::Luton.try_scribe(), Some("LTN"));
Serde
您可以使用相同的语法派生serde::Serialize
和serde::Deserialize
。
use serde::{Serialize, Deserialize};
use enumscribe::{EnumSerialize, EnumDeserialize};
#[derive(EnumSerialize, EnumDeserialize, PartialEq, Eq, Clone, Copy, Debug)]
enum Airport {
#[enumscribe(str = "LHR")]
Heathrow,
#[enumscribe(str = "LGW")]
Gatwick,
#[enumscribe(str = "LTN")]
Luton,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct Flight {
takeoff: Airport,
landing: Airport,
}
// There are probably much more economical ways of making this journey
let flight = Flight {
takeoff: Airport::Heathrow,
landing: Airport::Gatwick,
};
let flight_json = r#"{"takeoff":"LHR","landing":"LGW"}"#;
assert_eq!(serde_json::to_string(&flight).unwrap(), flight_json.to_owned());
assert_eq!(serde_json::from_str::<Flight>(flight_json).unwrap(), flight);
特质表
以下是一个表格,展示了根据您的枚举应派生哪些特质
是否使用了ignore ? |
是否使用了other ? |
转换为字符串 | 从字符串转换 |
---|---|---|---|
否 | 否 | ScribeStaticStr |
TryUnscribe |
否 | 是 | ScribeCowStr |
Unscribe |
是 | 否 | TryScribeStaticStr |
TryUnscribe |
是 | 是 | TryScribeCowStr |
Unscribe |
还有ScribeString
和TryScribeString
特质,它们可以在与ScribeCowStr
和TryScribeCowStr
相同的场景中使用。这些特质产生一个String
而不是一个Cow<'static, str>
,因此它们将始终执行分配。因此,除非您真的不希望出于任何原因使用Cow
,否则您应该首选ScribeCowStr
特质而不是ScribeString
特质。
依赖关系
~170KB