首页 > 解决方案 > 具有定制包装类型的柴油

问题描述

我有自定义类型作为其他类型的包装器,不能在 Diesel 中安全使用:

use uuid::Uuid;

pub schema Post {
  id: PostId,
  title: String,
  body: String
}

pub schema PostId {value: Uuid}

我不能将这些自定义包装器与 Diesel 一起使用。我收到的错误消息如下:

#[derive(Insertable)]
the trait `diesel::Expression` is not implemented for `models::PostId`

我试图寻找有关转换自定义类型的示例,到目前为止,我看到的两种方法是实现AsExpressiontrait 或FromSqlandToSql特征,但到目前为止我看到的示例是针对枚举类型的,我可以t 推断除了前者之外的两种方法之间有什么区别似乎是一种较旧的方法,也不是这些特征的预期实现是什么。

标签: rustrust-diesel

解决方案


您需要实现这三个提到的特征 + 更多。AsExpression+FromSqlRow由相应的派生实现。FromSqlToSql需要手动实现。

use diesel::deserialize::{self, FromSql};
use diesel::pg::Pg;
use diesel::serialize::{self, ToSql};
use std::io::Write;

#[derive(AsExpression, FromSqlRow)]
#[sql_type = "diesel::sql_types::Uuid"]
pub schema PostId {
    value: uuid::Uuid,
}

impl FromSql<diesel::sql_types::Uuid, Pg> for PostId {
    fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
        <uuid::Uuid as FromSql<diesel::sql_types::Uuid, Pg>>::from_sql(bytes)
            .map(|value| PostId { value })
    }
}

impl ToSql<diesel::sql_types::Uuid, Pg> for PostId {
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
        <uuid::Uuid as ToSql<diesel::sql_types::Uuid, Pg>>::to_sql(&self.0, out)
    }
}

推荐阅读