I have a users
table that I'm trying to add a role
field to with Diesel:
#[derive(Debug, Clone, Queryable, Insertable)]
pub struct User {
// other fields
pub role: Role,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsExpression)]
#[sql_type = "diesel::sql_types::VarChar"]
pub enum Role {
User,
Admin,
}
/// manual impls for FromSql<VarChar, Pg>, ToSql<VarChar, Pg> and FromSqlRow<VarChar, Pg>
For compatibility reasons, I'd like these to be represented in the database as varchars ("user"
and "admin"
), but would like to use an enum on the Rust side for extra type safety.
However, with the setup I currently have, I get:
error[E0277]: the trait bound `Role: Queryable<Text, Pg>` is not satisfied
--> src/state/database/users.rs:47:32
|
47 | self.exec(|conn| users.load(conn)).await
| ^^^^ the trait `Queryable<Text, Pg>` is not implemented for `Role`
|
= note: required because of the requirements on the impl of `Queryable<(diesel::sql_types::Uuid, Text, Text, diesel::sql_types::Timestamp, Text), Pg>` for `(model::types::UserId, model::types::Email, model::types::PasswordHash, NaiveDateTime, Role)`
= note: 1 redundant requirement hidden
= note: required because of the requirements on the impl of `Queryable<(diesel::sql_types::Uuid, Text, Text, diesel::sql_types::Timestamp, Text), Pg>` for `user::User`
= note: required because of the requirements on the impl of `LoadQuery<PooledConnection<diesel::r2d2::ConnectionManager<diesel::PgConnection>>, user::User>` for `schema::users::table`
From what I understand, in diesel, VarChar
and Text
are the same type (i.e. aliased). If I change all of the VarChar
s to Text
s in my impls, the error persists.
I'm confident it's not the other fields/field order because if I replace Role
with a plain String
, it works.
I feel like I must be missing something, this seems like fairly common behaviour. Perhaps there's another trait I need to implement?
FWIW, my schema for the users table looks like:
table! {
users (id) {
id -> Uuid,
email -> Varchar,
password_hash -> Varchar,
created_at -> Timestamp,
role -> Varchar,
}
}
Using postgres 14, rust 1.57, diesel 1.4.8
You need to derive FromSqlRow
as well. It will generate the necessary FromSqlRow
and Queryable
impl for your type.