Issue with Rust and working with Sea ORM for ULID as Primary Key

231 views Asked by At
use sea_orm::{Value};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use std::convert::{TryFrom, From};
use std::str::FromStr;
use ulid::{Ulid};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomUlid(pub Ulid);

impl CustomUlid {
    pub fn new(ulid: Ulid) -> Self {
        CustomUlid(ulid)
    }
}

impl Serialize for CustomUlid {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
    {
        serializer.serialize_str(&self.0.to_string())
    }
}

impl<'de> Deserialize<'de> for CustomUlid {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;

        // Replace this with the actual logic to convert a string into a Ulid
        match Ulid::from_str(&s) {
            Ok(ulid) => Ok(CustomUlid(ulid)),
            Err(e) => Err(serde::de::Error::custom(e)),
        }
    }
}

impl From<Ulid> for CustomUlid {
    fn from(ulid: Ulid) -> Self {
        CustomUlid(ulid)
    }
}

impl From<CustomUlid> for Value {
    fn from(custom_ulid: CustomUlid) -> Self {
        Value::String(Some(Box::new(custom_ulid.0.to_string())))
    }
}

impl TryFrom<Value> for CustomUlid {
    type Error = String; // You can define a more specific error type if needed

    fn try_from(value: Value) -> Result<Self, Self::Error> {
        match value {
            Value::String(Some(s)) => {
                // Replace this with the actual way to construct a Ulid from a string
                Ulid::from_str(&s)
                    .map(CustomUlid)
                    .map_err(|e| format!("Failed to parse ULID: {}", e))
            }
            _ => Err("Value is not a String".to_string()),
        }
    }
}


impl FromStr for CustomUlid {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ulid::from_str(s)
            .map(CustomUlid).map_err(|e| format!("Failed to parse ULID: {}", e))
    }
}

My MODEL

use std::str::FromStr;
use sea_orm::entity::prelude::*;
use sea_orm::{Set};
use serde::{Deserialize, Serialize};
use ulid::{Ulid};
use crate::infrastructure::types::custom_ulid::CustomUlid;
use sea_orm::EntityTrait;


#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "user")]
pub struct Model {
    #[sea_orm(primary_key, auto_increment = false)]
    pub id: CustomUlid,

    pub first_name: String,
}

impl Model {
    // A method to parse a string into CustomUlid
    pub fn parse_custom_ulid(s: String) -> Result<CustomUlid, String> {
        CustomUlid::from_str(&s)
    }
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {
    fn new() -> Self {
        Self {
            id: Set(CustomUlid(Ulid::new())),
            ..ActiveModelTrait::default()
        }
    }
}

The Error:

error[E0277]: the trait bound `CustomUlid: sea_orm::ActiveEnum` is not satisfied
  --> src/domain/user/model.rs:14:13
   |
14 |     pub id: CustomUlid,
   |             ^^^^^^^^^^ the trait `sea_orm::ActiveEnum` is not implemented for `CustomUlid`
   |
   = help: the following other types implement trait `TryFromU64`:
             (T0, T1)
             (T0, T1, T2)
             (T0, T1, T2, T3)
             (T0, T1, T2, T3, T4)
             (T0, T1, T2, T3, T4, T5)
             (T0, T1, T2, T3, T4, T5, T6)
             (T0, T1, T2, T3, T4, T5, T6, T7)
             (T0, T1, T2, T3, T4, T5, T6, T7, T8)
           and 29 others
   = note: required for `CustomUlid` to implement `TryFromU64`
note: required by a bound in `sea_orm::PrimaryKeyTrait::ValueType`
  --> /Users/toluwanimi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sea-orm-0.12.2/src/entity/primary_key.rs:49:11
   |
42 |     type ValueType: Sized
   |          --------- required by a bound in this associated type
...
49 |         + TryFromU64;
   |           ^^^^^^^^^^ required by this bound in `PrimaryKeyTrait::ValueType`

error[E0277]: the trait bound `CustomUlid: ValueType` is not satisfied
   --> src/domain/user/model.rs:10:39
    |
10  | #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
    |                                       ^^^^^^^^^^^^^^^^^ the trait `ValueType` is not implemented for `CustomUlid`
    |
    = help: the following other types implement trait `ValueType`:
              Cow<'_, str>
              JsonValue
              OffsetDateTime
              PrimitiveDateTime
              Vec<T>
              Vec<u8>
              bool
              char
            and 27 others
note: required by a bound in `sea_orm::Value::unwrap`
   --> /Users/toluwanimi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sea-query-0.30.0/src/value.rs:309:12
    |
307 |     pub fn unwrap<T>(self) -> T
    |            ------ required by a bound in this associated function
308 |     where
309 |         T: ValueType,
    |            ^^^^^^^^^ required by this bound in `Value::unwrap`
    = note: this error originates in the derive macro `DeriveEntityModel` (in Nightly builds, run with -Z macro-backtrace for more info)```
0

There are 0 answers