为泛型类型编写 Diesel CRUD 操作

cod*_*arm 4 crud rust rust-diesel

我正在尝试编写一个 Rust 箱,在使用Diesel创建简单的 CRUD 操作时,它会从用户那里删除一些样板代码

例如,如果您有Insertable一辆像这样的柴油机:

#[derive(Insertable)]
#[table_name = "users"]
pub struct UserCreate<'a> {
    pub email: String,
    pub hash: &'a [u8],
    pub first_name: Option<String>,
    pub family_name: Option<String>,
}
Run Code Online (Sandbox Code Playgroud)

我希望板条箱用户只需编写create<UserCreate>(model, pool), 将结构字段插入到数据库行中。

为此,我编写了以下函数签名(例如,简化的):

fn create<'a, C: 'a>(model: C, pool: DBPool)
where
    C: diesel::Identifiable,
    &'a C: diesel::Insertable<C::Table>,
{
    let conn = pool.get().unwrap();
    diesel::insert_into(C::table())
        .values(&model)
        .execute(&conn);
}
Run Code Online (Sandbox Code Playgroud)

问题是编译器抱怨 和Cat&C缺少一些特征边界.execute(&conn)缺少一些特征边界,我不太确定如何将它们放入子句中where,可能还有一种我不知道的更简单的方法。任何提示都非常受欢迎!

编译器输出:

error[E0277]: the trait bound `<<C as diesel::associations::HasTable>::Table as diesel::QuerySource>::FromClause: diesel::query_builder::QueryFragment<_>` is not satisfied
  --> database/src/users/models.rs:46:10
   |
46 |         .execute(&conn);
   |          ^^^^^^^ the trait `diesel::query_builder::QueryFragment<_>` is not implemented for `<<C as diesel::associations::HasTable>::Table as diesel::QuerySource>::FromClause`
   |
   = help: the following implementations were found:
             <&'a T as diesel::query_builder::QueryFragment<DB>>
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`
   = note: required because of the requirements on the impl of `diesel::query_dsl::load_dsl::ExecuteDsl<_, _>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`

error[E0277]: the trait bound `<&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values: diesel::query_builder::QueryFragment<_>` is not satisfied
  --> database/src/users/models.rs:46:10
   |
46 |         .execute(&conn);
   |          ^^^^^^^ the trait `diesel::query_builder::QueryFragment<_>` is not implemented for `<&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values`
   |
   = help: the following implementations were found:
             <&'a T as diesel::query_builder::QueryFragment<DB>>
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`
   = note: required because of the requirements on the impl of `diesel::query_dsl::load_dsl::ExecuteDsl<_, _>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`

error[E0277]: the trait bound `<&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values: diesel::insertable::CanInsertInSingleQuery<_>` is not satisfied
  --> database/src/users/models.rs:46:10
   |
46 |         .execute(&conn);
   |          ^^^^^^^ the trait `diesel::insertable::CanInsertInSingleQuery<_>` is not implemented for `<&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values`
   |
   = help: the following implementations were found:
             <&'a T as diesel::insertable::CanInsertInSingleQuery<DB>>
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`
   = note: required because of the requirements on the impl of `diesel::query_dsl::load_dsl::ExecuteDsl<_, _>` for `diesel::query_builder::InsertStatement<<C as diesel::associations::HasTable>::Table, <&C as diesel::Insertable<<C as diesel::associations::HasTable>::Table>>::Values>`

error: aborting due to 3 previous errors
Run Code Online (Sandbox Code Playgroud)

非常感谢!

小智 6

接受的答案是正确的,但可以通过使用更高的界限来变得不那么冗长

use diesel::query_builder::{InsertStatement};
use diesel::query_dsl::methods::{ExecuteDsl};

pub fn insert_into_table<T, M>(conn: &Pgconnection, table: T, records: M)
where
    T: Table,
    M: diesel::Insertable<T>,
    InsertStatement<T, M::Values>: ExecuteDsl<PgConnection>,
{
    diesel::insert_into(table)
        .values(records)
        .execute(conn);
}
Run Code Online (Sandbox Code Playgroud)