2 个不稳定版本
新 0.2.0 | 2024 年 8 月 26 日 |
---|---|
0.1.0 | 2024 年 8 月 26 日 |
#4 在 #tagged
每月 21 次下载
14KB
388 行
tagged-id
一个零成本的包装器,为资源标识符添加类型安全。
为什么?
这解决了两个问题
- 如果两个资源由相同的类型标识(例如,一个
User
和一个Device
,它们都由一个i32
标识),它们可能在应用程序代码中错误地交换。编译器无法帮助您解决这个问题,但这当然是不正确的。 - 当编写需要操作资源标识符的代码时,您通常需要查找 ID 的具体类型,以便编写函数签名和类型注解。在大多数情况下,ID 的本质并不重要,因此将其视为一个不透明类型更方便。
示例
use tagged_id::{Id, Identify};
struct User {
id: Id<User>, // id is a i32
some_field: String
}
impl Identifiable for User {
type InnerId = i32;
}
struct Device {
id: Id<Device>, // id is also a i32
some_value: i32
}
impl Identifiable for Device {
type InnerId = i32;
}
fn main() {
let user_id: Id<User> = Id::new(42);
let device_id: Id<Device> = Id::new(42);
// This does not compile since the tags are different.
assert_eq!(user_id, device_id);
}
Id<T>
继承内部类型的核心特质的实现。例如,如果 InnerId
是 Copy
,那么 Id<T>
也是 Copy
。
Id<T>
只是带有特质约束的内部类型的新类型包装器,这使得它成为一个零成本的抽象。
Cargo 功能标志
smartstring
:启用将字符串转换为CompactString
的From<&str>
实例。当禁用时,将启用String
的实例。serde
:启用对tagged-id
和支持它的依赖项(如smartstring
)的 serde 支持。sqlx-{postgres,mysql,sqlite}
:启用Encode
和Decode
实例,以便与相应的sqlx
后端透明使用。
依赖项
~0.5–14MB
~200K SLoC