1

I am using:

diesel = { version = "1.3.0", features = ["postgres", "chrono"] }

The struct Payment contains a custom type CentAmount. To make the containing struct insertable, I have implemented

  • AsExpression
  • FromSqlRow

as described in Simplify the support of custom types:

use diesel::expression::AsExpression;
use diesel::helper_types::AsExprOf;
use diesel::pg::Pg;
use diesel::row::Row;
use diesel::sql_types::{Integer, Nullable};
use diesel::types::FromSqlRow;
use std::error::Error;

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)]
pub struct CentAmount {
    cents: i32,
}

impl CentAmount {
    pub fn new(cents: i32) -> Self {
        assert!(cents >= 0);
        CentAmount { cents: cents }
    }
}

impl<'a> AsExpression<Nullable<Integer>> for &'a CentAmount {
    type Expression = AsExprOf<i32, Nullable<Integer>>;

    fn as_expression(self) -> Self::Expression {
        AsExpression::<Nullable<Integer>>::as_expression(self.cents)
    }
}

impl FromSqlRow<Integer, Pg> for CentAmount {
    fn build_from_row<R: Row<Pg>>(row: &mut R) -> Result<Self, Box<Error + Send + Sync>> {
        let cents = i32::build_from_row(row)?;
        Ok(CentAmount { cents })
    }
}

The struct is used here

#[derive(Queryable, Debug, Getters, Serialize, Deserialize, PartialEq, Insertable)]
#[table_name = "payments"]
pub struct Payment {
    pub id: Option<i32>,
    amount: CentAmount,
    leistung_id: i32,
    beschaeftiger_id: i32,
    payment_state: PaymentState,
    approval_date: Option<DateTime<Local>>,
}

I still get the error:

the trait `diesel::Expression` is not implemented for `model::cent_amount::CentAmount`

What am I missing?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
emunMuc
  • 11
  • 1
  • I believe your question is answered by the answers of [How do I implement Queryable and Insertable for custom field types in Diesel?](https://stackoverflow.com/q/49092437/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 13 '18 at 14:40
  • 1
    Thanks a lot for bringing me back to this post ;). I tried it before, but came across the the post from one of the maintainers. It seem that I was missing the `#[sql_type = "Integer"]` tag in my code. Can anyone elaborate on what it is used for ? @Shepmaster please mark it as answered. – emunMuc Jun 13 '18 at 15:08
  • 1
    I added some links to the duplicate answer about `sql_type`. TL;DR, that's how Diesel knows what underlying format to store the data in the database. – Shepmaster Jun 13 '18 at 15:19

0 Answers0