Search code examples
rustrust-cargorust-dieselrust-chrono

Trait diesel::Expression not implemented for NaiveDate, but it is for NaiveDateTime


I am trying to use chrono::NaiveDate as a database model field. Here is the model:

use chrono::{NaiveDate, NaiveDateTime};
use diesel::{Insertable, Queryable};
use serde::{Deserialize, Serialize};

use crate::schema::users;

#[derive(Debug, Serialize, Deserialize, Associations, Identifiable, Queryable)]
#[table_name = "users"]
pub struct User {
    pub id: uuid::Uuid,
    pub password_hash: String,
    pub is_active: bool,

    pub is_premium: bool,
    pub premium_expiration: Option<NaiveDate>,

    pub email: String,
    pub first_name: String,
    pub last_name: String,
    pub date_of_birth: NaiveDate,
    pub currency: String,

    pub modified_timestamp: NaiveDateTime,
    pub created_timestamp: NaiveDateTime,
}

#[derive(Debug, Insertable)]
#[table_name = "users"]
pub struct NewUser<'a> {
    pub id: uuid::Uuid,
    pub password_hash: &'a str,
    pub is_active: bool,

    pub is_premium: bool,
    pub premium_expiration: Option<NaiveDate>,

    pub email: &'a str,
    pub first_name: &'a str,
    pub last_name: &'a str,
    pub date_of_birth: NaiveDate,
    pub currency: &'a str,

    pub modified_timestamp: NaiveDateTime,
    pub created_timestamp: NaiveDateTime,
}

When I run cargo check, I get the following errors from rustc:

error[E0277]: the trait bound `NaiveDate: diesel::Expression` is not satisfied
  --> src/models/user.rs:27:17
   |
27 | #[derive(Debug, Insertable)]
   |                 ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `NaiveDate`
   |
   = note: required because of the requirements on the impl of `AsExpression<diesel::sql_types::Nullable<diesel::sql_types::Timestamp>>` for `NaiveDate`
   = 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 `NaiveDate: diesel::Expression` is not satisfied
  --> src/models/user.rs:27:17
   |
27 | #[derive(Debug, Insertable)]
   |                 ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `NaiveDate`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&'insert NaiveDate`
   = note: required because of the requirements on the impl of `AsExpression<diesel::sql_types::Nullable<diesel::sql_types::Timestamp>>` for `&'insert NaiveDate`
   = 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 `NaiveDate: diesel::Expression` is not satisfied
  --> src/models/user.rs:27:17
   |
27 | #[derive(Debug, Insertable)]
   |                 ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `NaiveDate`
   |
   = note: required because of the requirements on the impl of `diesel::Expression` for `&NaiveDate`
   = note: required because of the requirements on the impl of `AsExpression<diesel::sql_types::Nullable<diesel::sql_types::Timestamp>>` for `&NaiveDate`
   = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

The relevant lines of my Cargo.toml:

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
diesel = { version = "1.4", features = ["postgres", "uuidv07", "r2d2", "chrono"] }

Running cargo tree | grep chrono gives the following output, indicating there is not a version conflict with chrono:

├── chrono v0.4.19
│   ├── chrono v0.4.19 (*)
│       ├── chrono v0.4.19 (*)

I have used NaiveDate before in diesel models and have had no problem deriving the Insertable macro. What am I missing here that is preventing the macro from implementing diesel::Expression for chono::NaiveDate while it appears to be implemented for chono::NaiveDateTime?


Solution

  • First of all your question is missing important information. This includes the corresponding table! call from your schema.

    Now the guessing what could possibly cause this based on the information you provided:

    The error message indicates that you try to insert a NaiveDate into a Timestamp field. That's just something that is not supported as a timestamp expects a data and a time value, while a NaiveDate only provides a date value. You can see a list of out of the box supported type mappings for diesel in the documentation of each SQL type. For example for Timestamp here