NyxCode / ormx

bringing orm-like features to sqlx
MIT License
287 stars 32 forks source link

fix #[ormx(by_ref)] for non-Copy custom types #25

Closed Punie closed 2 years ago

Punie commented 2 years ago

This PR aims to fix the combined usage of #[ormx(by_ref, custom_type)]:

As an example, let's say I have a non-Copy custome sqlx type as part of my model, and I want to #[derive(ormx::Table)] with the insertable option:

#[derive(sqlx::Type, Clone, Debug)]
#[sqlx(transparent)]
struct EmailAddress(String);

#[ormx::Table, Clone, Debug]
#[ormx(table = "user", id = id, insertable)]
struct User {
  #[ormx(default)]
  id: Uuid,

  #[ormx(custom_type)]
  email: EmailAddress,
}

In that case, I get the following error:

error[E0507]: cannot move out of `self.email` which is behind a shared reference
  --> src/domain/user.rs:5:10
   |
 5 | #[derive(ormx::Table, Clone, Debug)]
   |          ^^^^^^^^^^^ move occurs because `self.email` has type `EmailAddress`, which does not implement the `Copy` trait
   |
   = note: this error originates in the derive macro `Table` (in Nightly builds, run with -Z macro-backtrace for more info)

So naturally, I reach out to the field option #[ormx(by_ref)] for email:

-  #[ormx(custom_type)]
+  #[ormx(by_ref, custom_type)]
   email: EmailAddress

Now, the error becomes:

error[E0605]: non-primitive cast: `&EmailAddress` as `EmailAddress`
  --> server/src/domain/user.rs:5:10
   |
 5 | #[derive(ormx::Table, Clone, Debug)]
   |          ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
   |
   = note: this error originates in the derive macro `Table` (in Nightly builds, run with -Z macro-backtrace for more info)

tl;dr: The code generated when both by_ref and custom_type are used in conjunction doesn't add the & to the type in the cast, hence the error. This PR fixes that omission.

NyxCode commented 2 years ago

great, thanks!