diff --git a/issues/400/Cargo.toml b/issues/400/Cargo.toml new file mode 100644 index 00000000..d6200d12 --- /dev/null +++ b/issues/400/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] +# A separate workspace + +[package] +name = "sea-orm-issues-400" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls" ]} diff --git a/issues/400/src/main.rs b/issues/400/src/main.rs new file mode 100644 index 00000000..a9db43c3 --- /dev/null +++ b/issues/400/src/main.rs @@ -0,0 +1,3 @@ +mod model; + +pub fn main() {} diff --git a/issues/400/src/model.rs b/issues/400/src/model.rs new file mode 100644 index 00000000..a53eeb74 --- /dev/null +++ b/issues/400/src/model.rs @@ -0,0 +1,79 @@ +use std::marker::PhantomData; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "model")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: AccountId, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} + +#[derive(Clone, Debug, PartialEq)] +pub struct AccountId(Uuid, PhantomData); + +impl AccountId { + pub fn new(id: Uuid) -> Self { + AccountId(id, PhantomData) + } +} + +impl From> for Uuid { + fn from(account_id: AccountId) -> Self { + account_id.0 + } +} + +impl sea_orm::TryFromU64 for AccountId { + fn try_from_u64(_n: u64) -> Result { + Err(sea_orm::DbErr::Exec(format!( + "{} cannot be converted from u64", + stringify!(AccountId) + ))) + } +} + +impl From> 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 { + 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 { + 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 + } +} diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 7309a6c4..1cd9134b 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -1,10 +1,10 @@ use crate::util::{escape_rust_keyword, trim_starting_raw_identifier}; use heck::CamelCase; use proc_macro2::{Ident, Span, TokenStream}; -use quote::{format_ident, quote, quote_spanned}; +use quote::{quote, quote_spanned}; use syn::{ parse::Error, punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, Fields, - Lit, Meta, + Lit, LitStr, Meta, Type, }; /// Method to derive an Model @@ -256,7 +256,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res }; if col_type.is_empty() { let field_span = field.span(); - let ty = format_ident!("{}", temp); + let ty: Type = LitStr::new(temp, field_span).parse()?; let def = quote_spanned! { field_span => { std::convert::Into::::into( <#ty as sea_orm::sea_query::ValueType>::column_type()