diesel-derive-enum icon indicating copy to clipboard operation
diesel-derive-enum copied to clipboard

Not able to make the crate work "the trait `diesel::Expression` is not implemented for `enums::AccountStatus`"

Open williamdes opened this issue 4 years ago • 9 comments

I added your crate and did the config in: https://github.com/air-balloon/api/commit/b5ec7ce8d7c514d62b6bef97dee9034fbede4acb

Summary of the problems:

  • It does generate a schema with account_status -> Enum, that does not work
  • I get the trait diesel::Expression is not implemented for enums::AccountStatus errors

If I apply this diff (to un-hack my compiling version)

diff --git a/src/models/user.rs b/src/models/user.rs
index d6df1ab..7621b41 100644
--- a/src/models/user.rs
+++ b/src/models/user.rs
@@ -13,7 +13,7 @@ pub struct User {
     pub username: String,
     pub first_name: String,
     pub last_name: String,
-    pub account_status: String,
+    pub account_status: AccountStatus,
     pub timezone: Option<String>,
     pub first_log_in_at: Option<NaiveDateTime>,
     pub last_log_in_at: Option<NaiveDateTime>,
@@ -29,7 +29,7 @@ pub struct NewUser<'a> {
     pub username: &'a String,
     pub first_name: &'a String,
     pub last_name: &'a String,
-    pub account_status: &'a String,
+    pub account_status: &'a AccountStatus,
     pub timezone: Option<&'a String>,
     pub first_log_in_at: Option<&'a NaiveDateTime>,
     pub last_log_in_at: Option<&'a NaiveDateTime>,
diff --git a/src/schema.rs b/src/schema.rs
index d727291..25ccfb8 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -9,7 +9,7 @@ table! {
         username -> Varchar,
         first_name -> Varchar,
         last_name -> Varchar,
-        account_status -> Varchar,
+        account_status -> AccountStatus,
         timezone -> Nullable<Varchar>,
         first_log_in_at -> Nullable<Timestamp>,
         last_log_in_at -> Nullable<Timestamp>,

I get the following errors

   Compiling api v0.1.0 (/mnt/Dev/@air-balloon/api)
error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
  --> src/models/user.rs:23:10
   |
23 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&'a enums::AccountStatus`
   = note: required because of the requirements on the impl of `AsExpression<enums::AccountStatus>` for `&'a enums::AccountStatus`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
  --> src/models/user.rs:23:10
   |
23 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&enums::AccountStatus`
   = note: required because of the requirements on the impl of `AsExpression<enums::AccountStatus>` for `&enums::AccountStatus`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
  --> src/models/user.rs:23:10
   |
23 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&'a enums::AccountStatus`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `enums::AccountStatus: diesel::Expression` is not satisfied
  --> src/models/user.rs:23:10
   |
23 | #[derive(Insertable)]
   |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `enums::AccountStatus`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&enums::AccountStatus`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `api`

To learn more, run the command again with --verbose.

Thank you in advance for helping me, I am new to Rust and am stuck on this error. I checked in your tests folder but did not find something that helped, that said I applied all valid examples into mine.

williamdes avatar Jun 08 '21 23:06 williamdes

The line

+        account_status -> AccountStatus,

should read

+        account_status -> AccountStatusMapping,

Take a look at the README for more information.

adwhit avatar Jun 09 '21 19:06 adwhit

Hi

Thank you for this information, but I do not manage to make the type detection work so I still have to edit the schema file by hand Can you help?

williamdes avatar Jun 09 '21 19:06 williamdes

This is a basic problem with how Diesel generates a schema and is not really under control of this crate. There is a suggested solution here: https://github.com/adwhit/diesel-derive-enum/issues/53. Basically, make a 'dummy' module where you re-export the Mapping type under a different name, and import the module inside the diesel.toml. I haven't tried it but it should work. There is more discussion here: https://github.com/adwhit/diesel-derive-enum/issues/56

adwhit avatar Jun 09 '21 19:06 adwhit

This fixed all errors as you expected: https://github.com/air-balloon/api/commit/8d8c52634c9dba8bf495fbbbb2f2c178d572cff4

That said it still does not detect my enum and creates this diff when I run the migrate command:

diff --git a/src/schema.rs b/src/schema.rs
index ac9656d..93626f1 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -9,7 +9,7 @@ table! {
         username -> Varchar,
         first_name -> Varchar,
         last_name -> Varchar,
-        account_status -> AccountStatusMapping,
+        account_status -> Enum,
         timezone -> Nullable<Varchar>,
         first_log_in_at -> Nullable<Timestamp>,
         last_log_in_at -> Nullable<Timestamp>,

I tried the re-export method but I made this error whatever I tried

error[E0412]: cannot find type `AccountStatusMapping` in this scope
  --> src/schema.rs:12:27
   |
12 |         account_status -> AccountStatusMapping,
   |                           ^^^^^^^^^^^^^^^^^^^^ not found in this scope
   |
   = note: consider importing this struct:
           crate::models::enums::AccountStatusMapping

williamdes avatar Jun 09 '21 21:06 williamdes

Ah, I see you are using MariaDB. It seems that Diesel does it's enum name mangling differently to Postgres. Your options are to a) re-export AccountStatusMapping as Enum inside your dummy module b) Rename AccountStatusMapping to Enum with the DieselType annotation c) use the 'patch' feature of Diesel to patch the schema after it has been generated.

adwhit avatar Jun 09 '21 22:06 adwhit

Yup, MariaDB a) and b) will forbid using more than one enum 😕 c) looks like a long term hack I will probably opt in

Do you think you can have a chance to get this fixed here ? Reading the tests I was afraid this repository would be mostly compatible Postgres for the enums, was I right ?

williamdes avatar Jun 09 '21 22:06 williamdes

The fundamental problem is that when generating the schema, Diesel looks at the database and decides that your type should be given the name Enum. This crate unfortunately cannot control how Diesel works and cannot change this fact, only work around it.

Note that this problem only occurs when generating the schema, which typically only has to be done once. When I have hit this problem before I have just hand-edited the schema.rs after the fact. Not ideal but not too problematic.

adwhit avatar Jun 10 '21 07:06 adwhit

I should add that this crate is intended to support every database that Diesel supports. But it happens to be that Postgres has the best support for enums and thus gives a better experience

adwhit avatar Jun 10 '21 09:06 adwhit

Okay, maybe a bunch of documentation would be cool so other mysql users dont waste time searching for something they will not find I suspected what you explained by reading the tests and did not see an obvious mysql example

Adding a mysql example and some notes on the readme could be possible?

williamdes avatar Jun 10 '21 09:06 williamdes

Closing since I do no recall what this was about exactly

williamdes avatar Oct 01 '22 09:10 williamdes