1 个不稳定版本
新版本 0.1.0 | 2024 年 8 月 13 日 |
---|
#418 在 Rust 模式
每月 106 次下载
12KB
156 行
Plectrum
plectrum
[^1] 是一个 Rust 包,它提供了一种简单的方法来将数据库(或任何数据源)中的查找表表示为 Rust 枚举。
快速示例
假设我们在 sqlite 数据库中有一个以下查找表
CREATE TABLE item_states (
id integer PRIMARY KEY,
label text NOT NULL UNIQUE
);
并且它包含以下数据
sqlite> SELECT * from item_states;
1|todo
2|in_progress
3|completed
4|parked
5|archived
使用由该包提供的 Plectrum
过程宏,我们可以定义一个枚举来表示它,如下所示
#[derive(Debug, Plectrum)]
#[plectrum(rename_all = "snake_case")]
enum ItemState {
Todo,
InProgress,
Completed,
Parked,
Archived,
}
这将允许我们使用该包提供的 Mapping
抽象来轻松地将枚举实例转换为相应的 id
或 value
(在这种情况下为标签)以及相反的操作
mapping.by_id(1) // Some(ItemState::Todo)
mapping.by_value("in_progress") // Some(ItemState::InProgress)
mapping.get_id(&ItemState::Parked) // Some(4)
为了使这个例子更简洁,我在这里省略了一部分,即告诉 plectrum
如何从数据库中获取查找表条目[^2]。这是通过为一个结构体实现 plectrum::DataSource
特性,然后使用该结构体实例初始化 plectrum::Mapping
来完成的。有关此例子的完整实现,请参阅 此处。
安装
cargo add plectrum --features derive
该 derive
功能提供了一个过程宏,它会自动为枚举实现 plectrum::Enum
特性。
如果您正在使用 sqlx 包与您的数据源交互,则建议指定 sqlx
功能。
cargo add plectrum --features derive,sqlx
此功能提供了 plectrum::Error::Sqlx
错误变体,它封装了一个 sqlx::Error
。请参阅 sqlite 示例 以了解使用方法。
大小写转换
《Plectrum》过程宏支持一个用于指定任何大小写转换的rename_all
属性,在将枚举变体名称映射到符合Rust惯例的UpperCamel
大小写时,与查找表中的值进行映射。
以下大小写转换受支持
UPPER CASE
小写
标题大小写
驼峰大小写
大驼峰大小写
蛇形大小写
UPPER_SNAKE_CASE
中划线大小写
UPPER-KEBAB-CASE
火车-大小写
平坦大小写
UPPERFLATCASE
请注意,选项名称是自解释的。
如果没有指定rename_all
属性,枚举变体名称本身将被视为查找表中的值。换句话说,值的默认大小写为UpperCamelCase
,但前提是遵循Rust的枚举变体名称惯例。
枚举与查找表之间的不一致性
通常,在初始化过程中创建一个plectrum::Mapping
结构体实例,此时将所有查找表条目加载到内存中,并映射到枚举变体。此时,可能存在查找表条目和枚举变体之间不一致的情况。例如
-
表中可能存在枚举变体未定义的条目。
-
可能存在查找表中不存在条目的枚举变体
在这种情况下,Mapping::load
函数将分别返回plectrum::Error::NotDefinedInCode
和plectrum::Error::NotFoundInDb
错误。
因为映射只在初始化过程中发生一次,这意味着如果向查找表添加条目或从查找表中删除条目,枚举定义也必须相应地修改(随后重启进程)。
上述错误充当了一个安全网,以尽早捕获任何不一致性,即进程将无法启动,这在大多数情况下比运行时错误要好得多。
示例
许可证
MIT(见LICENSE)。
[^1]:为什么叫plectrum
?这个lib之前被命名为lute
,简称LookUp Tables mapped to Enums。但这个名称已经在crates.io上被占用。我想到的plectrum
是一个与之密切相关且可用的名称!
[^2]:请注意,此crate 不提供类似ORM的功能,因此用户需要编写查询来从数据库中获取查找表条目。
依赖关系
~0–1.6MB
~31K SLoC