Cont. sea-orm-cli Implement derives & attributes parameters for entity generation (#1321)
* sea-orm-cli Implement derives & attributes parameters for entity generation (#1124) * implement derives & attributes for cli * fmt and clippy fix * use comma delimiter for attributes arg * Update help message use `'` instead of `"` to quote * Refactoring * remove unnecessary cloning Co-authored-by: Billy Chan <ccw.billy.123@gmail.com> * [CLI] generate model with extra derives and attributes * clippy Co-authored-by: Isaiah Gamble <77396670+tsar-boomba@users.noreply.github.com>
This commit is contained in:
parent
9282ce2ded
commit
384ac1bea6
@ -243,6 +243,24 @@ pub enum GenerateSubcommands {
|
|||||||
help = "Generate index file as `lib.rs` instead of `mod.rs`."
|
help = "Generate index file as `lib.rs` instead of `mod.rs`."
|
||||||
)]
|
)]
|
||||||
lib: bool,
|
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. `--derives 'ts_rs::Ts'`"
|
||||||
|
)]
|
||||||
|
model_extra_derives: Vec<String>,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
value_parser,
|
||||||
|
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)'`"#
|
||||||
|
)]
|
||||||
|
model_extra_attributes: Vec<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ pub async fn run_generate_command(
|
|||||||
with_copy_enums,
|
with_copy_enums,
|
||||||
date_time_crate,
|
date_time_crate,
|
||||||
lib,
|
lib,
|
||||||
|
model_extra_derives,
|
||||||
|
model_extra_attributes,
|
||||||
} => {
|
} => {
|
||||||
if verbose {
|
if verbose {
|
||||||
let _ = tracing_subscriber::fmt()
|
let _ = tracing_subscriber::fmt()
|
||||||
@ -168,6 +170,8 @@ pub async fn run_generate_command(
|
|||||||
lib,
|
lib,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
model_extra_derives,
|
||||||
|
model_extra_attributes,
|
||||||
);
|
);
|
||||||
let output = EntityTransformer::transform(table_stmts)?.generate(&writer_context);
|
let output = EntityTransformer::transform(table_stmts)?.generate(&writer_context);
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ pub struct EntityWriterContext {
|
|||||||
pub(crate) lib: bool,
|
pub(crate) lib: bool,
|
||||||
pub(crate) serde_skip_hidden_column: bool,
|
pub(crate) serde_skip_hidden_column: bool,
|
||||||
pub(crate) serde_skip_deserializing_primary_key: bool,
|
pub(crate) serde_skip_deserializing_primary_key: bool,
|
||||||
|
pub(crate) model_extra_derives: TokenStream,
|
||||||
|
pub(crate) model_extra_attributes: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WithSerde {
|
impl WithSerde {
|
||||||
@ -76,6 +78,37 @@ impl WithSerde {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts model_extra_derives argument to token stream
|
||||||
|
fn bonus_derive<T>(model_extra_derives: Vec<T>) -> TokenStream
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
model_extra_derives
|
||||||
|
.into_iter()
|
||||||
|
.map(Into::<String>::into)
|
||||||
|
.fold(TokenStream::default(), |acc, derive| {
|
||||||
|
let tokens: TokenStream = derive.parse().unwrap();
|
||||||
|
quote! { #acc, #tokens }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// convert attributes argument to token stream
|
||||||
|
fn bonus_attributes<T>(attributes: Vec<T>) -> TokenStream
|
||||||
|
where
|
||||||
|
T: Into<String>,
|
||||||
|
{
|
||||||
|
attributes.into_iter().map(Into::<String>::into).fold(
|
||||||
|
TokenStream::default(),
|
||||||
|
|acc, attribute| {
|
||||||
|
let tokens: TokenStream = attribute.parse().unwrap();
|
||||||
|
quote! {
|
||||||
|
#acc
|
||||||
|
#[#tokens]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for WithSerde {
|
impl FromStr for WithSerde {
|
||||||
type Err = crate::Error;
|
type Err = crate::Error;
|
||||||
|
|
||||||
@ -106,6 +139,8 @@ impl EntityWriterContext {
|
|||||||
lib: bool,
|
lib: bool,
|
||||||
serde_skip_deserializing_primary_key: bool,
|
serde_skip_deserializing_primary_key: bool,
|
||||||
serde_skip_hidden_column: bool,
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: Vec<String>,
|
||||||
|
model_extra_attributes: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
expanded_format,
|
expanded_format,
|
||||||
@ -116,6 +151,8 @@ impl EntityWriterContext {
|
|||||||
lib,
|
lib,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
model_extra_derives: bonus_derive(model_extra_derives),
|
||||||
|
model_extra_attributes: bonus_attributes(model_extra_attributes),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,6 +206,8 @@ impl EntityWriter {
|
|||||||
&context.schema_name,
|
&context.schema_name,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
&context.model_extra_derives,
|
||||||
|
&context.model_extra_attributes,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Self::gen_compact_code_blocks(
|
Self::gen_compact_code_blocks(
|
||||||
@ -178,6 +217,8 @@ impl EntityWriter {
|
|||||||
&context.schema_name,
|
&context.schema_name,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
&context.model_extra_derives,
|
||||||
|
&context.model_extra_attributes,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
Self::write(&mut lines, code_blocks);
|
Self::write(&mut lines, code_blocks);
|
||||||
@ -272,6 +313,7 @@ impl EntityWriter {
|
|||||||
lines.push("".to_owned());
|
lines.push("".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn gen_expanded_code_blocks(
|
pub fn gen_expanded_code_blocks(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
@ -279,6 +321,8 @@ impl EntityWriter {
|
|||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
serde_skip_deserializing_primary_key: bool,
|
serde_skip_deserializing_primary_key: bool,
|
||||||
serde_skip_hidden_column: bool,
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> Vec<TokenStream> {
|
) -> Vec<TokenStream> {
|
||||||
let mut imports = Self::gen_import(with_serde);
|
let mut imports = Self::gen_import(with_serde);
|
||||||
imports.extend(Self::gen_import_active_enum(entity));
|
imports.extend(Self::gen_import_active_enum(entity));
|
||||||
@ -292,6 +336,8 @@ impl EntityWriter {
|
|||||||
date_time_crate,
|
date_time_crate,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
model_extra_derives,
|
||||||
|
model_extra_attributes,
|
||||||
),
|
),
|
||||||
Self::gen_column_enum(entity),
|
Self::gen_column_enum(entity),
|
||||||
Self::gen_primary_key_enum(entity),
|
Self::gen_primary_key_enum(entity),
|
||||||
@ -306,6 +352,7 @@ impl EntityWriter {
|
|||||||
code_blocks
|
code_blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn gen_compact_code_blocks(
|
pub fn gen_compact_code_blocks(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
@ -313,6 +360,8 @@ impl EntityWriter {
|
|||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
serde_skip_deserializing_primary_key: bool,
|
serde_skip_deserializing_primary_key: bool,
|
||||||
serde_skip_hidden_column: bool,
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> Vec<TokenStream> {
|
) -> Vec<TokenStream> {
|
||||||
let mut imports = Self::gen_import(with_serde);
|
let mut imports = Self::gen_import(with_serde);
|
||||||
imports.extend(Self::gen_import_active_enum(entity));
|
imports.extend(Self::gen_import_active_enum(entity));
|
||||||
@ -325,6 +374,8 @@ impl EntityWriter {
|
|||||||
schema_name,
|
schema_name,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
model_extra_derives,
|
||||||
|
model_extra_attributes,
|
||||||
),
|
),
|
||||||
Self::gen_compact_relation_enum(entity),
|
Self::gen_compact_relation_enum(entity),
|
||||||
];
|
];
|
||||||
@ -413,6 +464,8 @@ impl EntityWriter {
|
|||||||
date_time_crate: &DateTimeCrate,
|
date_time_crate: &DateTimeCrate,
|
||||||
serde_skip_deserializing_primary_key: bool,
|
serde_skip_deserializing_primary_key: bool,
|
||||||
serde_skip_hidden_column: bool,
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let column_names_snake_case = entity.get_column_names_snake_case();
|
let column_names_snake_case = entity.get_column_names_snake_case();
|
||||||
let column_rs_types = entity.get_column_rs_types(date_time_crate);
|
let column_rs_types = entity.get_column_rs_types(date_time_crate);
|
||||||
@ -424,7 +477,8 @@ impl EntityWriter {
|
|||||||
let extra_derive = with_serde.extra_derive();
|
let extra_derive = with_serde.extra_derive();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive)]
|
#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #model_extra_derives)]
|
||||||
|
#model_extra_attributes
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#(
|
#(
|
||||||
#serde_attributes
|
#serde_attributes
|
||||||
@ -603,6 +657,7 @@ impl EntityWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn gen_compact_model_struct(
|
pub fn gen_compact_model_struct(
|
||||||
entity: &Entity,
|
entity: &Entity,
|
||||||
with_serde: &WithSerde,
|
with_serde: &WithSerde,
|
||||||
@ -610,6 +665,8 @@ impl EntityWriter {
|
|||||||
schema_name: &Option<String>,
|
schema_name: &Option<String>,
|
||||||
serde_skip_deserializing_primary_key: bool,
|
serde_skip_deserializing_primary_key: bool,
|
||||||
serde_skip_hidden_column: bool,
|
serde_skip_hidden_column: bool,
|
||||||
|
model_extra_derives: &TokenStream,
|
||||||
|
model_extra_attributes: &TokenStream,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let table_name = entity.table_name.as_str();
|
let table_name = entity.table_name.as_str();
|
||||||
let column_names_snake_case = entity.get_column_names_snake_case();
|
let column_names_snake_case = entity.get_column_names_snake_case();
|
||||||
@ -676,11 +733,12 @@ impl EntityWriter {
|
|||||||
let extra_derive = with_serde.extra_derive();
|
let extra_derive = with_serde.extra_derive();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel #if_eq_needed #extra_derive #model_extra_derives)]
|
||||||
#[sea_orm(
|
#[sea_orm(
|
||||||
#schema_name
|
#schema_name
|
||||||
table_name = #table_name
|
table_name = #table_name
|
||||||
)]
|
)]
|
||||||
|
#model_extra_attributes
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#(
|
#(
|
||||||
#attrs
|
#attrs
|
||||||
@ -721,6 +779,7 @@ impl EntityWriter {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
|
entity::writer::{bonus_attributes, bonus_derive},
|
||||||
Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation,
|
Column, ConjunctRelation, DateTimeCrate, Entity, EntityWriter, PrimaryKey, Relation,
|
||||||
RelationType, WithSerde,
|
RelationType, WithSerde,
|
||||||
};
|
};
|
||||||
@ -1314,6 +1373,8 @@ mod tests {
|
|||||||
&None,
|
&None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1332,6 +1393,8 @@ mod tests {
|
|||||||
&Some("public".to_owned()),
|
&Some("public".to_owned()),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1350,6 +1413,8 @@ mod tests {
|
|||||||
&Some("schema_name".to_owned()),
|
&Some("schema_name".to_owned()),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1404,6 +1469,8 @@ mod tests {
|
|||||||
&None,
|
&None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1422,6 +1489,8 @@ mod tests {
|
|||||||
&Some("public".to_owned()),
|
&Some("public".to_owned()),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1440,6 +1509,8 @@ mod tests {
|
|||||||
&Some("schema_name".to_owned()),
|
&Some("schema_name".to_owned()),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -1456,85 +1527,226 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gen_with_serde() -> io::Result<()> {
|
fn test_gen_with_serde() -> 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_serde/cake_none.rs"))?,
|
||||||
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
|
&cake_entity,
|
||||||
|
&WithSerde::None,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen_with_derives() -> io::Result<()> {
|
||||||
let mut cake_entity = setup().get_mut(0).unwrap().clone();
|
let mut cake_entity = setup().get_mut(0).unwrap().clone();
|
||||||
|
|
||||||
assert_eq!(cake_entity.get_table_name_snake_case(), "cake");
|
assert_eq!(cake_entity.get_table_name_snake_case(), "cake");
|
||||||
|
|
||||||
// Compact code blocks
|
// Compact code blocks
|
||||||
assert_serde_variant_results(
|
assert_eq!(
|
||||||
&cake_entity,
|
comparable_file_string(include_str!(
|
||||||
&(
|
"../../tests/compact_with_derives/cake_none.rs"
|
||||||
include_str!("../../tests/compact_with_serde/cake_none.rs").into(),
|
))?,
|
||||||
WithSerde::None,
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
None,
|
&cake_entity,
|
||||||
),
|
&WithSerde::None,
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
&DateTimeCrate::Chrono,
|
||||||
)?;
|
&None,
|
||||||
assert_serde_variant_results(
|
false,
|
||||||
&cake_entity,
|
false,
|
||||||
&(
|
&TokenStream::new(),
|
||||||
include_str!("../../tests/compact_with_serde/cake_serialize.rs").into(),
|
&TokenStream::new(),
|
||||||
WithSerde::Serialize,
|
))
|
||||||
None,
|
);
|
||||||
),
|
assert_eq!(
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
comparable_file_string(include_str!("../../tests/compact_with_derives/cake_one.rs"))?,
|
||||||
)?;
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
assert_serde_variant_results(
|
&cake_entity,
|
||||||
&cake_entity,
|
&WithSerde::None,
|
||||||
&(
|
&DateTimeCrate::Chrono,
|
||||||
include_str!("../../tests/compact_with_serde/cake_deserialize.rs").into(),
|
&None,
|
||||||
WithSerde::Deserialize,
|
false,
|
||||||
None,
|
false,
|
||||||
),
|
&bonus_derive(vec!["ts_rs::TS"]),
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
&TokenStream::new(),
|
||||||
)?;
|
))
|
||||||
assert_serde_variant_results(
|
);
|
||||||
&cake_entity,
|
assert_eq!(
|
||||||
&(
|
comparable_file_string(include_str!(
|
||||||
include_str!("../../tests/compact_with_serde/cake_both.rs").into(),
|
"../../tests/compact_with_derives/cake_multiple.rs"
|
||||||
WithSerde::Both,
|
))?,
|
||||||
None,
|
generated_to_string(EntityWriter::gen_compact_code_blocks(
|
||||||
),
|
&cake_entity,
|
||||||
Box::new(EntityWriter::gen_compact_code_blocks),
|
&WithSerde::None,
|
||||||
)?;
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&bonus_derive(vec!["ts_rs::TS", "utoipa::ToSchema"]),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
// Expanded code blocks
|
// Expanded code blocks
|
||||||
assert_serde_variant_results(
|
assert_eq!(
|
||||||
&cake_entity,
|
comparable_file_string(include_str!(
|
||||||
&(
|
"../../tests/expanded_with_derives/cake_none.rs"
|
||||||
include_str!("../../tests/expanded_with_serde/cake_none.rs").into(),
|
))?,
|
||||||
WithSerde::None,
|
generated_to_string(EntityWriter::gen_expanded_code_blocks(
|
||||||
None,
|
&cake_entity,
|
||||||
),
|
&WithSerde::None,
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
&DateTimeCrate::Chrono,
|
||||||
)?;
|
&None,
|
||||||
assert_serde_variant_results(
|
false,
|
||||||
&cake_entity,
|
false,
|
||||||
&(
|
&TokenStream::new(),
|
||||||
include_str!("../../tests/expanded_with_serde/cake_serialize.rs").into(),
|
&TokenStream::new(),
|
||||||
WithSerde::Serialize,
|
))
|
||||||
None,
|
);
|
||||||
),
|
assert_eq!(
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
comparable_file_string(include_str!(
|
||||||
)?;
|
"../../tests/expanded_with_derives/cake_one.rs"
|
||||||
assert_serde_variant_results(
|
))?,
|
||||||
&cake_entity,
|
generated_to_string(EntityWriter::gen_expanded_code_blocks(
|
||||||
&(
|
&cake_entity,
|
||||||
include_str!("../../tests/expanded_with_serde/cake_deserialize.rs").into(),
|
&WithSerde::None,
|
||||||
WithSerde::Deserialize,
|
&DateTimeCrate::Chrono,
|
||||||
None,
|
&None,
|
||||||
),
|
false,
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
false,
|
||||||
)?;
|
&bonus_derive(vec!["ts_rs::TS"]),
|
||||||
assert_serde_variant_results(
|
&TokenStream::new(),
|
||||||
&cake_entity,
|
))
|
||||||
&(
|
);
|
||||||
include_str!("../../tests/expanded_with_serde/cake_both.rs").into(),
|
assert_eq!(
|
||||||
WithSerde::Both,
|
comparable_file_string(include_str!(
|
||||||
None,
|
"../../tests/expanded_with_derives/cake_multiple.rs"
|
||||||
),
|
))?,
|
||||||
Box::new(EntityWriter::gen_expanded_code_blocks),
|
generated_to_string(EntityWriter::gen_expanded_code_blocks(
|
||||||
)?;
|
&cake_entity,
|
||||||
|
&WithSerde::None,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&bonus_derive(vec!["ts_rs::TS", "utoipa::ToSchema"]),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
// Make the `name` column of `cake` entity as hidden column
|
// Make the `name` column of `cake` entity as hidden column
|
||||||
cake_entity.columns[1].name = "_name".into();
|
cake_entity.columns[1].name = "_name".into();
|
||||||
@ -1542,8 +1754,7 @@ mod tests {
|
|||||||
assert_serde_variant_results(
|
assert_serde_variant_results(
|
||||||
&cake_entity,
|
&cake_entity,
|
||||||
&(
|
&(
|
||||||
include_str!("../../tests/compact_with_serde/cake_serialize_with_hidden_column.rs")
|
include_str!("../../tests/compact_with_serde/cake_serialize_with_hidden_column.rs"),
|
||||||
.into(),
|
|
||||||
WithSerde::Serialize,
|
WithSerde::Serialize,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
@ -1554,8 +1765,7 @@ mod tests {
|
|||||||
&(
|
&(
|
||||||
include_str!(
|
include_str!(
|
||||||
"../../tests/expanded_with_serde/cake_serialize_with_hidden_column.rs"
|
"../../tests/expanded_with_serde/cake_serialize_with_hidden_column.rs"
|
||||||
)
|
),
|
||||||
.into(),
|
|
||||||
WithSerde::Serialize,
|
WithSerde::Serialize,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
@ -1568,7 +1778,7 @@ mod tests {
|
|||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn assert_serde_variant_results(
|
fn assert_serde_variant_results(
|
||||||
cake_entity: &Entity,
|
cake_entity: &Entity,
|
||||||
entity_serde_variant: &(String, WithSerde, Option<String>),
|
entity_serde_variant: &(&str, WithSerde, Option<String>),
|
||||||
generator: Box<
|
generator: Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&Entity,
|
&Entity,
|
||||||
@ -1577,6 +1787,8 @@ mod tests {
|
|||||||
&Option<String>,
|
&Option<String>,
|
||||||
bool,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
|
&TokenStream,
|
||||||
|
&TokenStream,
|
||||||
) -> Vec<TokenStream>,
|
) -> Vec<TokenStream>,
|
||||||
>,
|
>,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
@ -1605,6 +1817,8 @@ mod tests {
|
|||||||
&entity_serde_variant.2,
|
&entity_serde_variant.2,
|
||||||
serde_skip_deserializing_primary_key,
|
serde_skip_deserializing_primary_key,
|
||||||
serde_skip_hidden_column,
|
serde_skip_hidden_column,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold(TokenStream::new(), |mut acc, tok| {
|
.fold(TokenStream::new(), |mut acc, tok| {
|
||||||
@ -1615,4 +1829,134 @@ mod tests {
|
|||||||
assert_eq!(expected.to_string(), generated.to_string());
|
assert_eq!(expected.to_string(), generated.to_string());
|
||||||
Ok(())
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#]),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#, "ts(export)"]),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&TokenStream::new(),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#]),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
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,
|
||||||
|
&DateTimeCrate::Chrono,
|
||||||
|
&None,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
&TokenStream::new(),
|
||||||
|
&bonus_attributes(vec![r#"serde(rename_all = "camelCase")"#, "ts(export)"]),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generated_to_string(generated: Vec<TokenStream>) -> String {
|
||||||
|
generated
|
||||||
|
.into_iter()
|
||||||
|
.fold(TokenStream::new(), |mut acc, tok| {
|
||||||
|
acc.extend(tok);
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn comparable_file_string(file: &str) -> io::Result<String> {
|
||||||
|
let mut reader = BufReader::new(file.as_bytes());
|
||||||
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
reader.read_until(b'\n', &mut Vec::new())?;
|
||||||
|
|
||||||
|
let mut line = String::new();
|
||||||
|
while reader.read_line(&mut line)? > 0 {
|
||||||
|
lines.push(line.to_owned());
|
||||||
|
line.clear();
|
||||||
|
}
|
||||||
|
let content = lines.join("");
|
||||||
|
let expected: TokenStream = content.parse().unwrap();
|
||||||
|
|
||||||
|
Ok(expected.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_attributes/cake_none.rs
Normal file
35
sea-orm-codegen/tests/compact_with_attributes/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
36
sea-orm-codegen/tests/compact_with_attributes/cake_one.rs
Normal file
36
sea-orm-codegen/tests/compact_with_attributes/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_none.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
35
sea-orm-codegen/tests/compact_with_derives/cake_one.rs
Normal file
35
sea-orm-codegen/tests/compact_with_derives/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {
|
||||||
|
#[sea_orm(has_many = "super::fruit::Entity")]
|
||||||
|
Fruit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
78
sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs
Normal file
78
sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_none.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_none.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
77
sea-orm-codegen/tests/expanded_with_derives/cake_one.rs
Normal file
77
sea-orm-codegen/tests/expanded_with_derives/cake_one.rs
Normal file
@ -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<String> ,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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<super::fruit::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::Fruit.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Related<super::filling::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
super::cake_filling::Relation::Filling.def()
|
||||||
|
}
|
||||||
|
fn via() -> Option<RelationDef> {
|
||||||
|
Some(super::cake_filling::Relation::Cake.def().rev())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
Loading…
x
Reference in New Issue
Block a user