Fix DeriveActiveEnum requires additional imports (#1154)

* fix: Support deriving ActiveEnum without importing EnumIter, Iden, and ActiveEnum

* style: Fix format

* DeriveActiveEnum without depending on sea_query::Iden derive macros

* [issues] add tests

* Fix [issues] features

Co-authored-by: Naoki Ikeguchi <me@s6n.jp>
This commit is contained in:
Billy Chan 2022-10-27 00:17:46 +08:00 committed by GitHub
parent 564092fc98
commit 1497c2c7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 87 additions and 7 deletions

17
issues/1143/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[workspace]
# A separate workspace
[package]
name = "sea-orm-issues-1143"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
serde = "^1"
tokio = { version = "^1", features = ["rt", "rt-multi-thread", "macros"] }
[dependencies.sea-orm]
path = "../../"
default-features = false
features = ["macros", "runtime-tokio-native-tls"]

View File

@ -0,0 +1 @@
pub mod sea_orm_active_enums;

View File

@ -0,0 +1,28 @@
use sea_orm::entity::prelude::*;
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "String(Some(1))")]
pub enum Category {
#[sea_orm(string_value = "B")]
Big,
#[sea_orm(string_value = "S")]
Small,
}
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
pub enum Color {
#[sea_orm(num_value = 0)]
Black,
#[sea_orm(num_value = 1)]
White,
}
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "tea")]
pub enum Tea {
#[sea_orm(string_value = "EverydayTea")]
EverydayTea,
#[sea_orm(string_value = "BreakfastTea")]
BreakfastTea,
}

4
issues/1143/src/main.rs Normal file
View File

@ -0,0 +1,4 @@
mod entity;
#[tokio::main]
async fn main() {}

View File

@ -6,4 +6,4 @@ publish = false
[dependencies] [dependencies]
core = { path = "../core" } core = { path = "../core" }
sea-orm = { path = "../../../", default-features = false, features = ["macros", "sqlx-sqlite", "runtime-async-std-native-tls"] } sea-orm = { path = "../../../", default-features = false, features = ["macros", "tests-cfg", "sqlx-sqlite", "runtime-async-std-native-tls"] }

View File

@ -13,5 +13,5 @@ tokio = { version = "1.20.0", features = ["rt-multi-thread", "macros"] }
[dependencies.sea-orm] [dependencies.sea-orm]
path = "../../" # remove this line in your own project path = "../../" # remove this line in your own project
features = ["runtime-tokio-rustls", "sqlx-sqlite", "macros"] features = ["runtime-tokio-rustls", "tests-cfg", "sqlx-sqlite", "macros"]
default-features = false default-features = false

View File

@ -250,14 +250,25 @@ impl ActiveEnum {
.collect(); .collect();
quote!( quote!(
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, Iden)] #[derive(Debug, Clone, PartialEq, Eq, sea_orm::EnumIter)]
pub enum #enum_variant_iden { pub enum #enum_variant_iden {
#( #(
#[iden = #str_variants]
#enum_variants, #enum_variants,
)* )*
} }
#[automatically_derived]
impl sea_orm::sea_query::Iden for #enum_variant_iden {
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
write!(s, "{}", match self {
#(
Self::#enum_variants => #str_variants,
)*
}).unwrap();
}
}
#[automatically_derived]
impl #ident { impl #ident {
pub fn iden_values() -> Vec<sea_orm::sea_query::DynIden> { pub fn iden_values() -> Vec<sea_orm::sea_query::DynIden> {
<#enum_variant_iden as sea_orm::strum::IntoEnumIterator>::iter() <#enum_variant_iden as sea_orm::strum::IntoEnumIterator>::iter()
@ -271,10 +282,16 @@ impl ActiveEnum {
}; };
quote!( quote!(
#[derive(Debug, Clone, PartialEq, Eq, Iden)] #[derive(Debug, Clone, PartialEq, Eq)]
#[iden = #enum_name]
pub struct #enum_name_iden; pub struct #enum_name_iden;
#[automatically_derived]
impl sea_orm::sea_query::Iden for #enum_name_iden {
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
write!(s, "{}", #enum_name).unwrap();
}
}
#impl_enum_variant_iden #impl_enum_variant_iden
#[automatically_derived] #[automatically_derived]
@ -357,7 +374,7 @@ impl ActiveEnum {
#[automatically_derived] #[automatically_derived]
impl std::fmt::Display for #ident { impl std::fmt::Display for #ident {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let v: sea_orm::sea_query::Value = self.to_value().into(); let v: sea_orm::sea_query::Value = <Self as sea_orm::ActiveEnum>::to_value(&self).into();
write!(f, "{}", v) write!(f, "{}", v)
} }
} }

View File

@ -539,6 +539,19 @@ pub fn derive_active_model_behavior(input: TokenStream) -> TokenStream {
/// - For `string_value`, value should be passed as string, i.e. `string_value = "A"` /// - For `string_value`, value should be passed as string, i.e. `string_value = "A"`
/// - For `num_value`, value should be passed as integer, i.e. `num_value = 1` or `num_value = 1i32` /// - For `num_value`, value should be passed as integer, i.e. `num_value = 1` or `num_value = 1i32`
/// - Note that only one of it can be specified, and all variants of an enum have to annotate with the same `*_value` macro attribute /// - Note that only one of it can be specified, and all variants of an enum have to annotate with the same `*_value` macro attribute
///
/// # Usage
///
/// ```
/// use sea_orm::{entity::prelude::*, DeriveActiveEnum};
///
/// #[derive(EnumIter, DeriveActiveEnum)]
/// #[sea_orm(rs_type = "i32", db_type = "Integer")]
/// pub enum Color {
/// Black = 0,
/// White = 1,
/// }
/// ```
#[proc_macro_derive(DeriveActiveEnum, attributes(sea_orm))] #[proc_macro_derive(DeriveActiveEnum, attributes(sea_orm))]
pub fn derive_active_enum(input: TokenStream) -> TokenStream { pub fn derive_active_enum(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);