12 个版本 (稳定)
2.2.0 |
|
---|---|
2.1.2 | 2024年4月19日 |
2.1.1 | 2024年3月17日 |
2.1.0 | 2023年6月9日 |
0.1.1 | 2018年3月2日 |
#255 在 数据库接口
每月14,419 次下载
在 17 个包中使用 (直接使用 6 个)
19KB
177 行
diesel-derive-newtype
在 Diesel 中轻松支持新类型。
安装
diesel-derive-newtype 根据其主版本号支持 Diesel -- 0.x 到 1.x 支持相应的 diesel 版本,2.0 支持柴油 2.0,2.1 支持柴油 2.1。
新功能仅针对当前支持的 Diesel 版本开发。
[dependencies]
diesel-derive-newtype = "2.1.0"
对于 Diesel 2.0.x,你必须告诉 cargo 不要升级 diesel-derive-newtype
[dependencies]
diesel-derive-newtype = "~ 2.0.0"
对于 Diesel 1.x
[dependencies]
diesel-derive-newtype = "1.0"
#[派生(DieselNewType)]
此包公开一个自定义派生宏 DieselNewType
,它为应用到的单字段元组结构体(NewType)实现了 ToSql
、FromSql
、FromSqlRow
、Queryable
、AsExpression
和 QueryId
。
此项目的目标是
derive(DieselNewType)
应该足以让你在 Diesel 中任何使用其底层类型的地方使用新类型。(可能成功)- 在使用你的新类型作为 Diesel 中的表达式元素时,应该得到与在 Rust 代码中相同的编译时保证(取决于你的需求,参见下面的 限制)。
示例
此实现
#[macro_use]
extern crate diesel_derive_newtype;
#[derive(DieselNewType)] // Doesn't need to be on its own line
#[derive(Debug, Hash, PartialEq, Eq)] // required by diesel
struct MyId(i64);
允许你在实体内部使用 MyId
结构体,就像它们是底层类型一样
table! {
my_items {
id -> Integer,
val -> Integer,
}
}
#[derive(Debug, PartialEq, Identifiable, Queryable)]
struct MyItem {
id: MyId,
val: u8,
}
哦哦。啊哈。
查看 测试 以获取更完整的示例。
限制
DieselNewtype
推导不会创建新的 数据库 类型,或者 Diesel 序列化类型。也就是说,如果你有 MyId(i64)
,这将使用 Diesel 的底层 BigInt
类型,这意味着尽管你的新类型可以在底层类型可以使用的任何地方使用,底层类型或任何其他具有相同底层类型的新类型也可以使用。
在某个时候,所有东西最终都会变成线上的比特,所以如果我们不这样做,Diesel 就必须在其他地方这样做,这是合理的默认行为(它很容易调试),但我正在调查自动生成新的代理类型,以便无法使用元组或错误类型化结构体构造插入语句。
下面是这个类型漏洞的示例
#[derive(Debug, Hash, PartialEq, Eq, DieselNewType)]
struct OneId(i64);
#[derive(Debug, Hash, PartialEq, Eq, DieselNewType)]
struct OtherId(i64);
#[derive(Debug, Clone, PartialEq, Identifiable, Insertable, Queryable)]
#[diesel(table_name = my_entities)]
pub struct MyEntity {
id: OneId,
val: i32,
}
fn darn(conn: &Connection) {
// shouldn't allow constructing the wrong type, but does
let OtherId: Vec<OtherId> = my_entities
.select(id)
.filter(id.eq(OtherId(1))) // shouldn't allow filtering by wrong type
.execute(conn).unwrap();
}
请参阅 tests/should-not-compile.rs
,了解我认为应该无法编译的内容。
我认为这个问题的根本原因在于 Diesel 实现了各种表达式方法,用于实现 AsExpression
的类型,基于 SQL 类型,而不关心 self
和 other
的 Rust 类型匹配。在一般情况下,这似乎是一个相当好的决定,但在这里有些不幸。
我希望找到一个解决方案,不需要手动为每个 *Expression
特性实现额外的边界,但到目前为止,你必须记住 Diesel 方法基本上会自动将你的数据转换为底层 SQL 类型。
发布
此工作流程使用
运行时注意,除非 diesel 有新版本发布,否则我们总是发布补丁版本
cargo readme > README.md
git diff --exit-code --quiet README.* || (git add README.* && git commit -m "chore: Update README")
cargo release patch
许可
diesel-derive-newtype 受以下任一许可的许可:
- Apache 许可证版本 2.0,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
您可选择。
欢迎提交补丁和错误报告!
依赖关系
~275–720KB
~17K SLoC