From 5f7833096d5f3ae3a1ee95a7a1779254386751ca Mon Sep 17 00:00:00 2001 From: tsar-boomba <77396670+tsar-boomba@users.noreply.github.com> Date: Sun, 16 Oct 2022 13:15:06 -0400 Subject: [PATCH 1/6] implement derives & attributes for cli --- sea-orm-cli/src/cli.rs | 19 + sea-orm-cli/src/commands/generate.rs | 4 + sea-orm-codegen/src/entity/writer.rs | 442 ++++++++++++++---- .../compact_with_attributes/cake_multiple.rs | 37 ++ .../compact_with_attributes/cake_none.rs | 35 ++ .../tests/compact_with_attributes/cake_one.rs | 36 ++ .../compact_with_derives/cake_multiple.rs | 35 ++ .../tests/compact_with_derives/cake_none.rs | 35 ++ .../tests/compact_with_derives/cake_one.rs | 35 ++ .../expanded_with_attributes/cake_multiple.rs | 79 ++++ .../expanded_with_attributes/cake_none.rs | 77 +++ .../expanded_with_attributes/cake_one.rs | 78 ++++ .../expanded_with_derives/cake_multiple.rs | 77 +++ .../tests/expanded_with_derives/cake_none.rs | 77 +++ .../tests/expanded_with_derives/cake_one.rs | 77 +++ 15 files changed, 1045 insertions(+), 98 deletions(-) create mode 100644 sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs create mode 100644 sea-orm-codegen/tests/compact_with_attributes/cake_none.rs create mode 100644 sea-orm-codegen/tests/compact_with_attributes/cake_one.rs create mode 100644 sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs create mode 100644 sea-orm-codegen/tests/compact_with_derives/cake_none.rs create mode 100644 sea-orm-codegen/tests/compact_with_derives/cake_one.rs create mode 100644 sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs create mode 100644 sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs create mode 100644 sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs create mode 100644 sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs create mode 100644 sea-orm-codegen/tests/expanded_with_derives/cake_none.rs create mode 100644 sea-orm-codegen/tests/expanded_with_derives/cake_one.rs diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index 827a17e14..132c02945 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -208,6 +208,25 @@ pub enum GenerateSubcommands { help = "Generate index file as `lib.rs` instead of `mod.rs`." )] lib: bool, + + #[clap( + value_parser, + long, + use_value_delimiter = true, + takes_value = true, + help = "Add extra derive macros to generated model structs (comma separated), ex. `ts_rs::Ts`" + )] + derives: Vec, + + #[clap( + value_parser, + long, + use_value_delimiter = true, + value_delimiter = ';', + takes_value = true, + help = r#"Add extra attributes to generated model struct, no need for `#[]` (semicolon separated), ex. `serde(rename_all = "camelCase")`"# + )] + attributes: Vec, }, } diff --git a/sea-orm-cli/src/commands/generate.rs b/sea-orm-cli/src/commands/generate.rs index 1686e878b..a7a62c571 100644 --- a/sea-orm-cli/src/commands/generate.rs +++ b/sea-orm-cli/src/commands/generate.rs @@ -27,6 +27,8 @@ pub async fn run_generate_command( with_copy_enums, date_time_crate, lib, + derives, + attributes, } => { if verbose { let _ = tracing_subscriber::fmt() @@ -169,6 +171,8 @@ pub async fn run_generate_command( let writer_context = EntityWriterContext::new( expanded_format, WithSerde::from_str(&with_serde).unwrap(), + derives, + attributes, with_copy_enums, date_time_crate.into(), schema_name, diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index c0a74e73d..a61fdf191 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -39,6 +39,8 @@ pub enum DateTimeCrate { pub struct EntityWriterContext { pub(crate) expanded_format: bool, pub(crate) with_serde: WithSerde, + pub(crate) derives: TokenStream, + pub(crate) attributes: TokenStream, pub(crate) with_copy_enums: bool, pub(crate) date_time_crate: DateTimeCrate, pub(crate) schema_name: Option, @@ -76,6 +78,39 @@ impl WithSerde { } } +/// Converts derives argument to token stream +fn bonus_derive(derives: Vec) -> TokenStream { + let bonus_derive = derives + .into_iter() + .fold(TokenStream::default(), |derives, derive| { + if !derive.is_empty() { + let tokens: TokenStream = derive.parse().unwrap(); + quote! { #derives, #tokens } + } else { + derives + } + }); + + bonus_derive +} + +/// convert attributes argument to token stream +fn bonus_attributes(attributes: Vec) -> TokenStream { + let attributes = attributes + .into_iter() + .filter(|attr| !attr.is_empty()) + .map(|attr| format!("#[{attr}]")) + .fold(TokenStream::default(), |attributes, attribute| { + let tokens: TokenStream = attribute.parse().unwrap(); + quote! { + #attributes + #tokens + } + }); + + attributes +} + impl FromStr for WithSerde { type Err = crate::Error; @@ -99,6 +134,8 @@ impl EntityWriterContext { pub fn new( expanded_format: bool, with_serde: WithSerde, + derives: Vec, + attributes: Vec, with_copy_enums: bool, date_time_crate: DateTimeCrate, schema_name: Option, @@ -107,6 +144,8 @@ impl EntityWriterContext { Self { expanded_format, with_serde, + derives: bonus_derive(derives), + attributes: bonus_attributes(attributes), with_copy_enums, date_time_crate, schema_name, @@ -151,6 +190,8 @@ impl EntityWriter { Self::gen_expanded_code_blocks( entity, &context.with_serde, + &context.derives, + &context.attributes, &context.date_time_crate, &context.schema_name, ) @@ -158,6 +199,8 @@ impl EntityWriter { Self::gen_compact_code_blocks( entity, &context.with_serde, + &context.derives, + &context.attributes, &context.date_time_crate, &context.schema_name, ) @@ -257,6 +300,8 @@ impl EntityWriter { pub fn gen_expanded_code_blocks( entity: &Entity, with_serde: &WithSerde, + derives: &TokenStream, + attributes: &TokenStream, date_time_crate: &DateTimeCrate, schema_name: &Option, ) -> Vec { @@ -266,7 +311,7 @@ impl EntityWriter { imports, Self::gen_entity_struct(), Self::gen_impl_entity_name(entity, schema_name), - Self::gen_model_struct(entity, with_serde, date_time_crate), + Self::gen_model_struct(entity, with_serde, derives, attributes, date_time_crate), Self::gen_column_enum(entity), Self::gen_primary_key_enum(entity), Self::gen_impl_primary_key(entity, date_time_crate), @@ -283,6 +328,8 @@ impl EntityWriter { pub fn gen_compact_code_blocks( entity: &Entity, with_serde: &WithSerde, + derives: &TokenStream, + attributes: &TokenStream, date_time_crate: &DateTimeCrate, schema_name: &Option, ) -> Vec { @@ -290,7 +337,14 @@ impl EntityWriter { imports.extend(Self::gen_import_active_enum(entity)); let mut code_blocks = vec![ imports, - Self::gen_compact_model_struct(entity, with_serde, date_time_crate, schema_name), + Self::gen_compact_model_struct( + entity, + with_serde, + derives, + attributes, + date_time_crate, + schema_name, + ), Self::gen_compact_relation_enum(entity), ]; code_blocks.extend(Self::gen_impl_related(entity)); @@ -377,15 +431,22 @@ impl EntityWriter { pub fn gen_model_struct( entity: &Entity, with_serde: &WithSerde, + derives: &TokenStream, + attributes: &TokenStream, date_time_crate: &DateTimeCrate, ) -> TokenStream { let column_names_snake_case = entity.get_column_names_snake_case(); let column_rs_types = entity.get_column_rs_types(date_time_crate); let if_eq_needed = entity.get_eq_needed(); let extra_derive = with_serde.extra_derive(); + // derives from --derives option + let bonus_derive = derives.clone(); + // attributes from --attributes option + let bonus_attributes = attributes.clone(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive)] + #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #bonus_derive)] + #bonus_attributes pub struct Model { #(pub #column_names_snake_case: #column_rs_types,)* } @@ -561,6 +622,8 @@ impl EntityWriter { pub fn gen_compact_model_struct( entity: &Entity, with_serde: &WithSerde, + derives: &TokenStream, + attributes: &TokenStream, date_time_crate: &DateTimeCrate, schema_name: &Option, ) -> TokenStream { @@ -620,13 +683,18 @@ impl EntityWriter { None => quote! {}, }; let extra_derive = with_serde.extra_derive(); + // derives from --derives option + let bonus_derive = derives.clone(); + // attributes from --attributes option + let bonus_attributes = attributes.clone(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive)] + #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive #bonus_derive)] #[sea_orm( #schema_name table_name = #table_name )] + #bonus_attributes pub struct Model { #( #attrs @@ -667,6 +735,7 @@ impl EntityWriter { #[cfg(test)] mod tests { use crate::{ + entity::writer::{bonus_attributes, bonus_derive}, Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation, RelationType, WithSerde, }; @@ -1173,6 +1242,8 @@ mod tests { EntityWriter::gen_expanded_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &None ) @@ -1189,6 +1260,8 @@ mod tests { EntityWriter::gen_expanded_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &Some("public".to_owned()) ) @@ -1205,6 +1278,8 @@ mod tests { EntityWriter::gen_expanded_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &Some("schema_name".to_owned()) ) @@ -1253,6 +1328,8 @@ mod tests { EntityWriter::gen_compact_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &None ) @@ -1269,6 +1346,8 @@ mod tests { EntityWriter::gen_compact_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &Some("public".to_owned()) ) @@ -1285,6 +1364,8 @@ mod tests { EntityWriter::gen_compact_code_blocks( entity, &crate::WithSerde::None, + &bonus_derive(vec![]), + &bonus_attributes(vec![]), &crate::DateTimeCrate::Chrono, &Some("schema_name".to_owned()) ) @@ -1308,93 +1389,270 @@ mod tests { assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); // Compact code blocks - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_none.rs").into(), - WithSerde::None, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_serialize.rs").into(), - WithSerde::Serialize, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_deserialize.rs").into(), - WithSerde::Deserialize, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/compact_with_serde/cake_both.rs").into(), - WithSerde::Both, - None, - ), - Box::new(EntityWriter::gen_compact_code_blocks), - )?; + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_serialize.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Serialize, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_deserialize.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Deserialize, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_serde/cake_both.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::Both, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); // Expanded code blocks - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_none.rs").into(), - WithSerde::None, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_serialize.rs").into(), - WithSerde::Serialize, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_deserialize.rs").into(), - WithSerde::Deserialize, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; - assert_serde_variant_results( - &cake_entity, - &( - include_str!("../../tests/expanded_with_serde/cake_both.rs").into(), - WithSerde::Both, - None, - ), - Box::new(EntityWriter::gen_expanded_code_blocks), - )?; + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_serialize.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Serialize, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_deserialize.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Deserialize, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_both.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::Both, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); Ok(()) } - #[allow(clippy::type_complexity)] - fn assert_serde_variant_results( - cake_entity: &Entity, - entity_serde_variant: &(String, WithSerde, Option), - generator: Box< - dyn Fn(&Entity, &WithSerde, &DateTimeCrate, &Option) -> Vec, - >, - ) -> io::Result<()> { - let mut reader = BufReader::new(entity_serde_variant.0.as_bytes()); + #[test] + fn test_gen_with_derives() -> io::Result<()> { + let cake_entity = setup().get(0).unwrap().clone(); + + assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); + + // Compact code blocks + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_derives/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_derives/cake_one.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &bonus_derive(vec!["ts_rs::TS".into()]), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_derives/cake_multiple.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &bonus_derive(vec!["ts_rs::TS".into(), "utoipa::ToSchema".into()]), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + + // Expanded code blocks + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_one.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &bonus_derive(vec!["ts_rs::TS".into()]), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_multiple.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &bonus_derive(vec!["ts_rs::TS".into(), "utoipa::ToSchema".into()]), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + + Ok(()) + } + + #[test] + fn test_gen_with_attributes() -> io::Result<()> { + let cake_entity = setup().get(0).unwrap().clone(); + + assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); + + // Compact code blocks + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_one.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into()]), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_multiple.rs"))?, + generated_to_string(EntityWriter::gen_compact_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into(), "ts(export)".into()]), + &DateTimeCrate::Chrono, + &None + )) + ); + + // Expanded code blocks + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_none.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &TokenStream::new(), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_one.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into()]), + &DateTimeCrate::Chrono, + &None + )) + ); + assert_eq!( + comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_multiple.rs"))?, + generated_to_string(EntityWriter::gen_expanded_code_blocks( + &cake_entity, + &WithSerde::None, + &TokenStream::new(), + &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into(), "ts(export)".into()]), + &DateTimeCrate::Chrono, + &None + )) + ); + + Ok(()) + } + + fn generated_to_string(generated: Vec) -> String { + generated + .into_iter() + .fold(TokenStream::new(), |mut acc, tok| { + acc.extend(tok); + acc + }) + .to_string() + } + + fn comparable_file_string(file: &str) -> io::Result { + let mut reader = BufReader::new(file.as_bytes()); let mut lines: Vec = Vec::new(); reader.read_until(b'\n', &mut Vec::new())?; @@ -1406,19 +1664,7 @@ mod tests { } let content = lines.join(""); let expected: TokenStream = content.parse().unwrap(); - let generated = generator( - cake_entity, - &entity_serde_variant.1, - &DateTimeCrate::Chrono, - &entity_serde_variant.2, - ) - .into_iter() - .fold(TokenStream::new(), |mut acc, tok| { - acc.extend(tok); - acc - }); - assert_eq!(expected.to_string(), generated.to_string()); - Ok(()) + Ok(expected.to_string()) } } diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs new file mode 100644 index 000000000..795a3b9b2 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs @@ -0,0 +1,37 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs new file mode 100644 index 000000000..d72ea6b21 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_none.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs b/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs new file mode 100644 index 000000000..11162ca1e --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_attributes/cake_one.rs @@ -0,0 +1,36 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +#[serde(rename_all = "camelCase")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs b/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs new file mode 100644 index 000000000..dd69de77c --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, ts_rs::TS, utoipa::ToSchema)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_none.rs b/sea-orm-codegen/tests/compact_with_derives/cake_none.rs new file mode 100644 index 000000000..d72ea6b21 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_none.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/compact_with_derives/cake_one.rs b/sea-orm-codegen/tests/compact_with_derives/cake_one.rs new file mode 100644 index 000000000..9a4aeaba0 --- /dev/null +++ b/sea-orm-codegen/tests/compact_with_derives/cake_one.rs @@ -0,0 +1,35 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, ts_rs::TS)] +#[sea_orm(table_name = "cake")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Text", nullable)] + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::fruit::Entity")] + Fruit, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs new file mode 100644 index 000000000..5c498d83c --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs @@ -0,0 +1,79 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs new file mode 100644 index 000000000..a540fad13 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs b/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs new file mode 100644 index 000000000..77da3181a --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs @@ -0,0 +1,78 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)] +#[serde(rename_all = "camelCase")] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs new file mode 100644 index 000000000..c04dfdd4d --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, ts_rs::TS, utoipa::ToSchema)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs new file mode 100644 index 000000000..a540fad13 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_none.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs b/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs new file mode 100644 index 000000000..a4ebdf829 --- /dev/null +++ b/sea-orm-codegen/tests/expanded_with_derives/cake_one.rs @@ -0,0 +1,77 @@ +//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0 + +use sea_orm::entity::prelude:: * ; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity; + +impl EntityName for Entity { + fn table_name(&self) -> &str { + "cake" + } +} + +#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, ts_rs::TS)] +pub struct Model { + pub id: i32, + pub name: Option , +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] +pub enum PrimaryKey { + Id, +} + +impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } +} + +#[derive(Copy, Clone, Debug, EnumIter)] +pub enum Relation { + Fruit, +} + +impl ColumnTrait for Column { + type EntityName = Entity; + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::Text.def().null(), + } + } +} + +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::Fruit => Entity::has_many(super::fruit::Entity).into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Fruit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + super::cake_filling::Relation::Filling.def() + } + fn via() -> Option { + Some(super::cake_filling::Relation::Cake.def().rev()) + } +} + +impl ActiveModelBehavior for ActiveModel {} From 863d0ab706e75ad56fef3303dbc5e53e95c59c4d Mon Sep 17 00:00:00 2001 From: tsar-boomba <77396670+tsar-boomba@users.noreply.github.com> Date: Sun, 16 Oct 2022 23:52:48 -0400 Subject: [PATCH 2/6] fmt and clippy fix --- sea-orm-codegen/src/entity/writer.rs | 87 +++++++++++++++++++--------- 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index a61fdf191..9b9f6b58a 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -80,7 +80,7 @@ impl WithSerde { /// Converts derives argument to token stream fn bonus_derive(derives: Vec) -> TokenStream { - let bonus_derive = derives + derives .into_iter() .fold(TokenStream::default(), |derives, derive| { if !derive.is_empty() { @@ -89,14 +89,12 @@ fn bonus_derive(derives: Vec) -> TokenStream { } else { derives } - }); - - bonus_derive + }) } /// convert attributes argument to token stream fn bonus_attributes(attributes: Vec) -> TokenStream { - let attributes = attributes + attributes .into_iter() .filter(|attr| !attr.is_empty()) .map(|attr| format!("#[{attr}]")) @@ -106,9 +104,7 @@ fn bonus_attributes(attributes: Vec) -> TokenStream { #attributes #tokens } - }); - - attributes + }) } impl FromStr for WithSerde { @@ -131,6 +127,7 @@ impl FromStr for WithSerde { } impl EntityWriterContext { + #[allow(clippy::too_many_arguments)] pub fn new( expanded_format: bool, with_serde: WithSerde, @@ -1401,7 +1398,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_serde/cake_serialize.rs"))?, + comparable_file_string(include_str!( + "../../tests/compact_with_serde/cake_serialize.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::Serialize, @@ -1412,7 +1411,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_serde/cake_deserialize.rs"))?, + comparable_file_string(include_str!( + "../../tests/compact_with_serde/cake_deserialize.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::Deserialize, @@ -1447,7 +1448,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_serialize.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_serde/cake_serialize.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::Serialize, @@ -1458,7 +1461,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_serde/cake_deserialize.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_serde/cake_deserialize.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::Deserialize, @@ -1490,8 +1495,10 @@ mod tests { assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); // Compact code blocks - assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_derives/cake_none.rs"))?, + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_derives/cake_none.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::None, @@ -1513,7 +1520,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_derives/cake_multiple.rs"))?, + comparable_file_string(include_str!( + "../../tests/compact_with_derives/cake_multiple.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::None, @@ -1526,7 +1535,9 @@ mod tests { // Expanded code blocks assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_none.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_none.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, @@ -1537,7 +1548,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_one.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_one.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, @@ -1548,7 +1561,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_derives/cake_multiple.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_derives/cake_multiple.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, @@ -1569,8 +1584,10 @@ mod tests { assert_eq!(cake_entity.get_table_name_snake_case(), "cake"); // Compact code blocks - assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_none.rs"))?, + assert_eq!( + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_none.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::None, @@ -1581,7 +1598,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_one.rs"))?, + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_one.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::None, @@ -1592,12 +1611,17 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/compact_with_attributes/cake_multiple.rs"))?, + comparable_file_string(include_str!( + "../../tests/compact_with_attributes/cake_multiple.rs" + ))?, generated_to_string(EntityWriter::gen_compact_code_blocks( &cake_entity, &WithSerde::None, &TokenStream::new(), - &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into(), "ts(export)".into()]), + &bonus_attributes(vec![ + r#"serde(rename_all = "camelCase")"#.into(), + "ts(export)".into() + ]), &DateTimeCrate::Chrono, &None )) @@ -1605,7 +1629,9 @@ mod tests { // Expanded code blocks assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_none.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_none.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, @@ -1616,7 +1642,9 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_one.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_one.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, @@ -1627,12 +1655,17 @@ mod tests { )) ); assert_eq!( - comparable_file_string(include_str!("../../tests/expanded_with_attributes/cake_multiple.rs"))?, + comparable_file_string(include_str!( + "../../tests/expanded_with_attributes/cake_multiple.rs" + ))?, generated_to_string(EntityWriter::gen_expanded_code_blocks( &cake_entity, &WithSerde::None, &TokenStream::new(), - &bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#.into(), "ts(export)".into()]), + &bonus_attributes(vec![ + r#"serde(rename_all = "camelCase")"#.into(), + "ts(export)".into() + ]), &DateTimeCrate::Chrono, &None )) From de39bd4e124b1237f6bad983cf385bb60e219d29 Mon Sep 17 00:00:00 2001 From: tsar-boomba <77396670+tsar-boomba@users.noreply.github.com> Date: Wed, 26 Oct 2022 18:26:56 -0400 Subject: [PATCH 3/6] use comma delimiter for attributes arg --- sea-orm-cli/src/cli.rs | 3 +-- sea-orm-codegen/src/entity/writer.rs | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index ed86211ef..021d1cbd5 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -244,9 +244,8 @@ pub enum GenerateSubcommands { value_parser, long, use_value_delimiter = true, - value_delimiter = ';', takes_value = true, - help = r#"Add extra attributes to generated model struct, no need for `#[]` (semicolon separated), ex. `serde(rename_all = "camelCase")`"# + help = r#"Add extra attributes to generated model struct, no need for `#[]` (comma separated), ex. `-- attributes "serde(rename_all = \"camelCase\")","ts(export)"`"# )] attributes: Vec, }, diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 86f00feeb..0afe73cdb 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -94,6 +94,7 @@ fn bonus_derive(derives: Vec) -> TokenStream { /// convert attributes argument to token stream fn bonus_attributes(attributes: Vec) -> TokenStream { + println!("{:?}", attributes); attributes .into_iter() .filter(|attr| !attr.is_empty()) From 0fcfe7d9ff50129f9b96f7aaa8e5a2d11ceb71c1 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Thu, 3 Nov 2022 16:01:25 +0800 Subject: [PATCH 4/6] Update help message use `'` instead of `"` to quote --- sea-orm-cli/src/cli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-orm-cli/src/cli.rs b/sea-orm-cli/src/cli.rs index 021d1cbd5..ab246d55c 100644 --- a/sea-orm-cli/src/cli.rs +++ b/sea-orm-cli/src/cli.rs @@ -236,7 +236,7 @@ pub enum GenerateSubcommands { long, use_value_delimiter = true, takes_value = true, - help = "Add extra derive macros to generated model structs (comma separated), ex. `ts_rs::Ts`" + help = "Add extra derive macros to generated model structs (comma separated), ex. `--derives 'ts_rs::Ts'`" )] derives: Vec, @@ -245,7 +245,7 @@ pub enum GenerateSubcommands { long, use_value_delimiter = true, takes_value = true, - help = r#"Add extra attributes to generated model struct, no need for `#[]` (comma separated), ex. `-- attributes "serde(rename_all = \"camelCase\")","ts(export)"`"# + help = r#"Add extra attributes to generated model struct, no need for `#[]` (comma separated), ex. `--attributes 'serde(rename_all = "camelCase")','ts(export)'`"# )] attributes: Vec, }, From 1e597908dea46408b496ebf3e0cb544c9eb39e1b Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Thu, 3 Nov 2022 16:01:38 +0800 Subject: [PATCH 5/6] Refactoring --- sea-orm-codegen/src/entity/writer.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 0afe73cdb..243777e79 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -83,27 +83,20 @@ fn bonus_derive(derives: Vec) -> TokenStream { derives .into_iter() .fold(TokenStream::default(), |derives, derive| { - if !derive.is_empty() { - let tokens: TokenStream = derive.parse().unwrap(); - quote! { #derives, #tokens } - } else { - derives - } + let tokens: TokenStream = derive.parse().unwrap(); + quote! { #derives, #tokens } }) } /// convert attributes argument to token stream fn bonus_attributes(attributes: Vec) -> TokenStream { - println!("{:?}", attributes); attributes .into_iter() - .filter(|attr| !attr.is_empty()) - .map(|attr| format!("#[{attr}]")) .fold(TokenStream::default(), |attributes, attribute| { let tokens: TokenStream = attribute.parse().unwrap(); quote! { #attributes - #tokens + #[#tokens] } }) } From ea0170727fbfdebd89cee03972fce42113633a34 Mon Sep 17 00:00:00 2001 From: tsar-boomba <77396670+tsar-boomba@users.noreply.github.com> Date: Thu, 3 Nov 2022 09:26:13 -0400 Subject: [PATCH 6/6] remove unnecessary cloning --- sea-orm-codegen/src/entity/writer.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/sea-orm-codegen/src/entity/writer.rs b/sea-orm-codegen/src/entity/writer.rs index 243777e79..3ae183d0a 100644 --- a/sea-orm-codegen/src/entity/writer.rs +++ b/sea-orm-codegen/src/entity/writer.rs @@ -430,14 +430,10 @@ impl EntityWriter { let column_rs_types = entity.get_column_rs_types(date_time_crate); let if_eq_needed = entity.get_eq_needed(); let extra_derive = with_serde.extra_derive(); - // derives from --derives option - let bonus_derive = derives.clone(); - // attributes from --attributes option - let bonus_attributes = attributes.clone(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #bonus_derive)] - #bonus_attributes + #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #derives)] + #attributes pub struct Model { #(pub #column_names_snake_case: #column_rs_types,)* } @@ -674,18 +670,14 @@ impl EntityWriter { None => quote! {}, }; let extra_derive = with_serde.extra_derive(); - // derives from --derives option - let bonus_derive = derives.clone(); - // attributes from --attributes option - let bonus_attributes = attributes.clone(); quote! { - #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive #bonus_derive)] + #[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive #derives)] #[sea_orm( #schema_name table_name = #table_name )] - #bonus_attributes + #attributes pub struct Model { #( #attrs