This issue is to outline the design of how to allow custom Enums to be used in SeaORM Entity.
It will be supported in 3 steps:
A proposed trait ActiveEnum (or DbEnum or OrmEnum etc) would be:
trait ActiveEnum {
type Value: ValueType;
fn to_value(&self) -> Self::Value;
fn try_from_value(v: &Self::Value) -> Result<Self, DbErr>;
fn db_type() -> ColumnDef;
}
A sample model would be like:
enum Category {
Big,
Small,
}
struct Model {
category: Category;
}
impl ActiveEnum for Category {
type Value = String;
fn to_value(&self) -> Self::Value {
match self {
Big => "B",
Small => "S",
}.to_owned()
}
fn from_value(v: &Self::Value) -> Result<Self, DbErr> {
match v.as_ref {
"B" => Ok(Self::Big),
"S" => Ok(Self::Small),
_ => Err(DbErr::TypeErr(format!("unexpected value for Category: {}", v))),
}
}
fn db_type() -> ColumnDef {
ColumnType::String(Some(1)).def
}
}
Such a trait should be all it takes for using a custom enum (we need to eliminate all boilerplate as in #196 (reply in thread)). And it will be converted automatically during Select, Insert and Update.
We can also make a DeriveActiveEnum macro to make it easier:
#[derive(DeriveActiveEnum)]
#[sea_orm(db_type = "String(Some(1))")]
enum Category {
#[sea_orm(string_value = "B")]
Big,
#[sea_orm(string_value = "S")]
Small,
}
(because of the excess String("B"), we'd better divide into string_value and num_value)
After some discussion with @acidic9, to support native enum in Postgres, we basically have to cast everywhere:
SELECT CAST("category" AS text) from "mytable";
INSERT INTO "mytable" ("category") VALUES (CAST($1 AS CategoryEnum));
UPDATE "mytable" SET "category" = CAST($1 AS CategoryEnum);
For MySQL, casting is not needed.
Ref: #196
This issue is to outline the design of how to allow custom Enums to be used in SeaORM Entity.
It will be supported in 3 steps:
A proposed trait
ActiveEnum(orDbEnumorOrmEnumetc) would be:A sample model would be like:
Such a trait should be all it takes for using a custom enum (we need to eliminate all boilerplate as in #196 (reply in thread)). And it will be converted automatically during Select, Insert and Update.
We can also make a
DeriveActiveEnummacro to make it easier:(because of the excess
String("B"), we'd better divide into string_value and num_value)After some discussion with @acidic9, to support native enum in Postgres, we basically have to cast everywhere:
For MySQL, casting is not needed.
Ref: #196