Skip to content

DeriveEntityModel failing compilation when using a stringy newtype #2811

@angrynode

Description

@angrynode

on v2 rc18 I'm trying to use a stringy newtype in a model which derives DeriveEntityModel. Ideally i'd like to have a simpler TryFrom-based implementation but i'm ok to have some boilerplate.

So i followed the new type docs and added boilerplate for my MagnetLink type:

#[cfg(feature = "sea_orm")]
impl From<MagnetLink> for sea_orm::sea_query::Value {
    fn from(m: MagnetLink) -> Self {
        Self::String(Some(m.to_string()))
    }
}

#[cfg(feature = "sea_orm")]
impl sea_orm::TryGetable for MagnetLink {
    fn try_get_by<I: sea_orm::ColIdx>(
        res: &sea_orm::QueryResult,
        index: I,
    ) -> Result<Self, sea_orm::error::TryGetError> {
        let val: String = res.try_get_by(index)?;
        Ok(MagnetLink::new(&val).map_err(|e| {
            sea_orm::error::TryGetError::DbErr(sea_orm::DbErr::TryIntoErr {
                from: "String",
                into: "MagnetLink",
                source: std::sync::Arc::new(e),
            })
        })?)
    }
}

#[cfg(feature = "sea_orm")]
impl sea_orm::sea_query::ValueType for MagnetLink {
    fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
        match v {
            // TODO: What to do with None String?
            // This should probably work with Option<MagnetLink> but not with MagnetLink
            // but i have no idea how sea orm works...
            sea_orm::Value::String(Some(s)) => {
                MagnetLink::new(&s).map_err(|_e| sea_orm::sea_query::ValueTypeErr)
            }
            _ => {
                Err(sea_orm::sea_query::ValueTypeErr)
            }
        }
    }

    fn type_name() -> String {
        "MagnetLink".to_string()
    }

    
    fn array_type() -> sea_orm::sea_query::ArrayType {
        sea_orm::sea_query::ArrayType::String
    }

    fn column_type() -> sea_orm::sea_query::ColumnType {
        sea_orm::sea_query::ColumnType::String(sea_orm::sea_query::table::StringLen::None)
    }
}

impl sea_orm::sea_query::Nullable for MagnetLink {
    fn null() -> sea_orm::sea_query::Value {
        sea_orm::sea_query::Value::String(None)
    }
}

This code compiles, and i'm probably doing it all wrong (since i don't know what do do to return an Option<MagnetLink> in TryGetable since apparently a nulled value is String(None) but that's another problem). However now my Model fails to compile:

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "magnet")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub torrent_id: String,
    #[sea_orm(column_type = "String")]
    pub magnet: MagnetLink,
    pub name: String,
    pub resolved: bool,
}

Compilation produces the error:

error[E0277]: the trait bound `fn(StringLen) -> ColumnType {sea_orm::ColumnType::String}: ColumnTypeTrait` is not satisfied
  --> src/database/magnet.rs:18:35
   |
18 | #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
   |                                   ^^^^^^^^^^^^^^^^^ the trait `ColumnTypeTrait` is not implemented for fn item `fn(StringLen) -> ColumnType {sea_orm::ColumnType::String}`
   |
   = help: the following other types implement trait `ColumnTypeTrait`:
             ColumnType
             sea_orm::ColumnDef
   = note: this error originates in the derive macro `DeriveEntityModel` (in Nightly builds, run with -Z macro-backtrace for more info)

This error may be produced by an error of my own making so it may not be a bug. I consider this a bug because:

  • i followed the docs and implemented the 4 traits for my custom type
  • the error produced does not mention my own types so i'm assuming either an assumption is wrong somewhere in the code or in the docs

I'd be happy if people can produce more examples (which we could link in the docs) about boilerplate to support new types in Models, because i probably did something very wrong :)

I did find this issue which mentioned needing to add ColumnTypeTrait to the current scope, but that doesn't solve the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions