Skip to content

Instantly share code, notes, and snippets.

@oscartbeaumont
Created December 24, 2021 02:45
Show Gist options
  • Save oscartbeaumont/94fc0412668609255df88f17a3de0cfa to your computer and use it in GitHub Desktop.
Save oscartbeaumont/94fc0412668609255df88f17a3de0cfa to your computer and use it in GitHub Desktop.
SeaORM Custom Value
# This code does not work.
# The DeriveEntityModel panics with error `message: `"AccountId<String>"` is not a valid identifier`
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, SimpleObject)]
#[sea_orm(table_name = "tenant")]
#[graphql(name = "Tenant")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: AccountId<String>,
pub name: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct AccountId<T>(Uuid, PhantomData<T>);
impl<T> AccountId<T> {
pub fn new(id: Uuid) -> Self {
AccountId(id, PhantomData)
}
}
impl<T> From<AccountId<T>> for Uuid {
fn from(account_id: AccountId<T>) -> Self {
account_id.0
}
}
#[Scalar]
impl<T: Send + Sync> ScalarType for AccountId<T> {
fn parse(_value: async_graphql::Value) -> InputValueResult<Self> {
unimplemented!();
}
fn to_value(&self) -> async_graphql::Value {
async_graphql::Value::String(self.0.to_string())
}
}
impl<T> sea_orm::TryFromU64 for AccountId<T> {
fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {
Err(sea_orm::DbErr::Exec(format!(
"{} cannot be converted from u64",
stringify!(AccountId<T>)
)))
}
}
impl<T> From<AccountId<T>> for sea_orm::Value {
fn from(source: AccountId<T>) -> Self {
sea_orm::Value::Uuid(Some(Box::new(source.into())))
}
}
impl<T> sea_orm::TryGetable for AccountId<T> {
fn try_get(
res: &sea_orm::QueryResult,
pre: &str,
col: &str,
) -> Result<Self, sea_orm::TryGetError> {
let val: Uuid = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?;
Ok(AccountId::<T>::new(val))
}
}
impl<T> sea_orm::sea_query::Nullable for AccountId<T> {
fn null() -> sea_orm::Value {
sea_orm::Value::Uuid(None)
}
}
impl<T> sea_orm::sea_query::ValueType for AccountId<T> {
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
match v {
sea_orm::Value::Uuid(Some(x)) => Ok(AccountId::<T>::new(*x)),
_ => Err(sea_orm::sea_query::ValueTypeErr),
}
}
fn type_name() -> String {
stringify!(AccountId).to_owned()
}
fn column_type() -> sea_orm::sea_query::ColumnType {
sea_orm::sea_query::ColumnType::Uuid
}
}
# This code works and builds off https://github.com/SeaQL/sea-orm/blob/master/issues/324/src/model.rs
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, SimpleObject)]
#[sea_orm(table_name = "tenant")]
#[graphql(name = "Tenant")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: AccountId,
pub name: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct AccountId(Uuid);
impl AccountId {
pub fn new(id: Uuid) -> Self {
AccountId(id)
}
}
impl From<AccountId> for Uuid {
fn from(account_id: AccountId) -> Self {
account_id.0
}
}
#[Scalar]
impl ScalarType for AccountId {
fn parse(_value: async_graphql::Value) -> InputValueResult<Self> {
unimplemented!();
}
fn to_value(&self) -> async_graphql::Value {
async_graphql::Value::String(self.0.to_string())
}
}
impl sea_orm::TryFromU64 for AccountId {
fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {
Err(sea_orm::DbErr::Exec(format!(
"{} cannot be converted from u64",
stringify!(AccountId)
)))
}
}
impl From<AccountId> for sea_orm::Value {
fn from(source: AccountId) -> Self {
sea_orm::Value::Uuid(Some(Box::new(source.into())))
}
}
impl sea_orm::TryGetable for AccountId {
fn try_get(
res: &sea_orm::QueryResult,
pre: &str,
col: &str,
) -> Result<Self, sea_orm::TryGetError> {
let val: Uuid = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?;
Ok(AccountId::new(val))
}
}
impl sea_orm::sea_query::Nullable for AccountId {
fn null() -> sea_orm::Value {
sea_orm::Value::Uuid(None)
}
}
impl sea_orm::sea_query::ValueType for AccountId {
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
match v {
sea_orm::Value::Uuid(Some(x)) => Ok(AccountId::new(*x)),
_ => Err(sea_orm::sea_query::ValueTypeErr),
}
}
fn type_name() -> String {
stringify!(AccountId).to_owned()
}
fn column_type() -> sea_orm::sea_query::ColumnType {
sea_orm::sea_query::ColumnType::Uuid
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment