#struct-fields #diesel #orm #table-column #sql #database #proc-macro

diesel-sort-struct-fields

宏用于排序结构体字段和 table! 列,以避免细微的错误

4个版本

0.1.3 2019年7月1日
0.1.2 2019年7月1日
0.1.1 2019年7月1日
0.1.0 2019年7月1日

#17#table-column

MIT 许可证

15KB
270

diesel-sort-struct-fields

宏用于排序结构体字段和 table! 列,以避免使用 Diesel 时的细微错误。

查看crate文档以获取使用示例和更多信息。


许可证:MIT


lib.rs:

宏用于排序结构体字段和 table! 列,以避免细微的错误。

Diesel将查询响应映射到结构体的方式是将行视为一个元组,并根据代码中字段的顺序分配字段。例如(非实际代码)

struct User {
    id: i32,
    name: String,
}

fn user_from_row(row: (i32, String)) -> User {
    User {
        id: row.0,
        name: row.1,
    }
}

这工作得很好,但如果在 table!idname 的顺序不同,它将以微妙的方式中断。因此,此代码无法编译

#[macro_use]
extern crate diesel;

use diesel::prelude::*;

table! {
    users {
        // order here doesn't match order in the struct
        name -> VarChar,
        id -> Integer,
    }
}

#[derive(Queryable)]
struct User {
    id: i32,
    name: String,
}

fn main() {
    let db = connect_to_db();

    users::table
        .select(users::all_columns)
        .load::<User>(&db)
        .unwrap();
}

fn connect_to_db() -> PgConnection {
    PgConnection::establish("postgres://127.0.0.1/diesel-sort-struct-fields").unwrap()
}

幸运的是,你得到一个类型错误,Diesel清楚地告诉你有问题。但是,如果 idname 的类型相同,你将不会得到类型错误。你只会遇到可能需要数小时才能追踪的细微错误(对我来说就是这样)。

这个crate通过一个简单的过程宏来防止这种情况,它会对你的模型结构体和 table! 的字段进行排序,这样你可以以任何顺序定义它们,但一旦代码到达编译器,顺序总是相同的。

示例

#[macro_use]
extern crate diesel;

use diesel_sort_struct_fields::{sort_columns, sort_fields};
use diesel::prelude::*;

#[sort_columns]
table! {
    users {
        name -> VarChar,
        id -> Integer,
    }
}

#[sort_fields]
#[derive(Queryable)]
struct User {
    id: i32,
    name: String,
}

fn main() {
    let db = connect_to_db();

    let users = users::table
        .select(users::all_columns)
        .load::<User>(&db)
        .unwrap();

    assert_eq!(0, users.len());
}

fn connect_to_db() -> PgConnection {
    PgConnection::establish("postgres://127.0.0.1/diesel-sort-struct-fields").unwrap()
}

依赖项

~2MB
~46K SLoC