Auto Generated ActiveEnum String Values And Model Column Names (#2170)
* WIP: Add Basic Support For Providing String Value For ActiveEnum Variants Based On Renaming Rules #2160 * WIP: Use Existing Case Style Handlers For Enum Rename Rules, Add Unit Tests For DeriveActiveEnum rename rules #2160 * WIP: Improve Implementation Of Name Case Parameters In ActiveEnum Macros #2160 * WIP: Implement Case Styles Based Name Generation For Columns In A Model #2160 * Fix Formatting #2160 * Rename Column Name And Enum Variant Renaming Macro Attributes #2160 * Revert Adding `Rename` Attribute For Column Names #2160 * Revert Unintended Formatting Changes #2160 * Fix formatting --------- Co-authored-by: Billy Chan <ccw.billy.123@gmail.com>
This commit is contained in:
parent
17b4081444
commit
33230ab3ad
@ -1,4 +1,5 @@
|
|||||||
use super::util::camel_case_with_escaped_non_uax31;
|
use super::util::camel_case_with_escaped_non_uax31;
|
||||||
|
use crate::strum::helpers::case_style::{CaseStyle, CaseStyleHelpers};
|
||||||
use heck::ToUpperCamelCase;
|
use heck::ToUpperCamelCase;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote, quote_spanned};
|
use quote::{format_ident, quote, quote_spanned};
|
||||||
@ -17,12 +18,14 @@ struct ActiveEnum {
|
|||||||
db_type: TokenStream,
|
db_type: TokenStream,
|
||||||
is_string: bool,
|
is_string: bool,
|
||||||
variants: Vec<ActiveEnumVariant>,
|
variants: Vec<ActiveEnumVariant>,
|
||||||
|
rename_all: Option<CaseStyle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ActiveEnumVariant {
|
struct ActiveEnumVariant {
|
||||||
ident: syn::Ident,
|
ident: syn::Ident,
|
||||||
string_value: Option<LitStr>,
|
string_value: Option<LitStr>,
|
||||||
num_value: Option<LitInt>,
|
num_value: Option<LitInt>,
|
||||||
|
rename: Option<CaseStyle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveEnum {
|
impl ActiveEnum {
|
||||||
@ -37,6 +40,7 @@ impl ActiveEnum {
|
|||||||
let mut db_type = Err(Error::TT(quote_spanned! {
|
let mut db_type = Err(Error::TT(quote_spanned! {
|
||||||
ident_span => compile_error!("Missing macro attribute `db_type`");
|
ident_span => compile_error!("Missing macro attribute `db_type`");
|
||||||
}));
|
}));
|
||||||
|
let mut rename_all_rule = None;
|
||||||
|
|
||||||
input
|
input
|
||||||
.attrs
|
.attrs
|
||||||
@ -67,6 +71,8 @@ impl ActiveEnum {
|
|||||||
} else if meta.path.is_ident("enum_name") {
|
} else if meta.path.is_ident("enum_name") {
|
||||||
let litstr: LitStr = meta.value()?.parse()?;
|
let litstr: LitStr = meta.value()?.parse()?;
|
||||||
enum_name = litstr.value();
|
enum_name = litstr.value();
|
||||||
|
} else if meta.path.is_ident("rename_all") {
|
||||||
|
rename_all_rule = Some((&meta).try_into()?);
|
||||||
} else {
|
} else {
|
||||||
return Err(meta.error(format!(
|
return Err(meta.error(format!(
|
||||||
"Unknown attribute parameter found: {:?}",
|
"Unknown attribute parameter found: {:?}",
|
||||||
@ -86,10 +92,13 @@ impl ActiveEnum {
|
|||||||
let mut is_string = false;
|
let mut is_string = false;
|
||||||
let mut is_int = false;
|
let mut is_int = false;
|
||||||
let mut variants = Vec::new();
|
let mut variants = Vec::new();
|
||||||
|
|
||||||
for variant in variant_vec {
|
for variant in variant_vec {
|
||||||
let variant_span = variant.ident.span();
|
let variant_span = variant.ident.span();
|
||||||
let mut string_value = None;
|
let mut string_value = None;
|
||||||
let mut num_value = None;
|
let mut num_value = None;
|
||||||
|
let mut rename_rule = None;
|
||||||
|
|
||||||
for attr in variant.attrs.iter() {
|
for attr in variant.attrs.iter() {
|
||||||
if !attr.path().is_ident("sea_orm") {
|
if !attr.path().is_ident("sea_orm") {
|
||||||
continue;
|
continue;
|
||||||
@ -105,6 +114,8 @@ impl ActiveEnum {
|
|||||||
// This is a placeholder to prevent the `display_value` proc_macro attribute of `DeriveDisplay`
|
// This is a placeholder to prevent the `display_value` proc_macro attribute of `DeriveDisplay`
|
||||||
// to be considered unknown attribute parameter
|
// to be considered unknown attribute parameter
|
||||||
meta.value()?.parse::<LitStr>()?;
|
meta.value()?.parse::<LitStr>()?;
|
||||||
|
} else if meta.path.is_ident("rename") {
|
||||||
|
rename_rule = Some((&meta).try_into()?);
|
||||||
} else {
|
} else {
|
||||||
return Err(meta.error(format!(
|
return Err(meta.error(format!(
|
||||||
"Unknown attribute parameter found: {:?}",
|
"Unknown attribute parameter found: {:?}",
|
||||||
@ -117,13 +128,16 @@ impl ActiveEnum {
|
|||||||
.map_err(Error::Syn)?;
|
.map_err(Error::Syn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_string && is_int {
|
if (is_string || rename_rule.is_some() || rename_all_rule.is_some()) && is_int {
|
||||||
return Err(Error::TT(quote_spanned! {
|
return Err(Error::TT(quote_spanned! {
|
||||||
ident_span => compile_error!("All enum variants should specify the same `*_value` macro attribute, either `string_value` or `num_value` but not both");
|
ident_span => compile_error!("All enum variants should specify the same `*_value` macro attribute, either `string_value` or `num_value` but not both");
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if string_value.is_none() && num_value.is_none() {
|
if string_value.is_none()
|
||||||
|
&& num_value.is_none()
|
||||||
|
&& rename_rule.or(rename_all_rule).is_none()
|
||||||
|
{
|
||||||
match variant.discriminant {
|
match variant.discriminant {
|
||||||
Some((_, Expr::Lit(exprlit))) => {
|
Some((_, Expr::Lit(exprlit))) => {
|
||||||
if let Lit::Int(litint) = exprlit.lit {
|
if let Lit::Int(litint) = exprlit.lit {
|
||||||
@ -155,7 +169,7 @@ impl ActiveEnum {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::TT(quote_spanned! {
|
return Err(Error::TT(quote_spanned! {
|
||||||
variant_span => compile_error!("Missing macro attribute, either `string_value` or `num_value` should be specified or specify repr[X] and have a value for every entry");
|
variant_span => compile_error!("Missing macro attribute, either `string_value`, `num_value` or `rename` should be specified or specify repr[X] and have a value for every entry");
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,6 +179,7 @@ impl ActiveEnum {
|
|||||||
ident: variant.ident,
|
ident: variant.ident,
|
||||||
string_value,
|
string_value,
|
||||||
num_value,
|
num_value,
|
||||||
|
rename: rename_rule,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +190,7 @@ impl ActiveEnum {
|
|||||||
db_type: db_type?,
|
db_type: db_type?,
|
||||||
is_string,
|
is_string,
|
||||||
variants,
|
variants,
|
||||||
|
rename_all: rename_all_rule,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +208,7 @@ impl ActiveEnum {
|
|||||||
db_type,
|
db_type,
|
||||||
is_string,
|
is_string,
|
||||||
variants,
|
variants,
|
||||||
|
rename_all,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let variant_idents: Vec<syn::Ident> = variants
|
let variant_idents: Vec<syn::Ident> = variants
|
||||||
@ -209,9 +226,13 @@ impl ActiveEnum {
|
|||||||
quote! { #string }
|
quote! { #string }
|
||||||
} else if let Some(num_value) = &variant.num_value {
|
} else if let Some(num_value) = &variant.num_value {
|
||||||
quote! { #num_value }
|
quote! { #num_value }
|
||||||
|
} else if let Some(rename_rule) = variant.rename.or(*rename_all) {
|
||||||
|
let variant_ident = variant.ident.convert_case(Some(rename_rule));
|
||||||
|
|
||||||
|
quote! { #variant_ident }
|
||||||
} else {
|
} else {
|
||||||
quote_spanned! {
|
quote_spanned! {
|
||||||
variant_span => compile_error!("Missing macro attribute, either `string_value` or `num_value` should be specified");
|
variant_span => compile_error!("Missing macro attribute, either `string_value`, `num_value` or `rename_all` should be specified");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -232,6 +253,9 @@ impl ActiveEnum {
|
|||||||
.string_value
|
.string_value
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|string_value| string_value.value())
|
.map(|string_value| string_value.value())
|
||||||
|
.or(variant
|
||||||
|
.rename
|
||||||
|
.map(|rename| variant.ident.convert_case(Some(rename))))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::strum::helpers::case_style::CaseStyle;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{quote, quote_spanned, ToTokens};
|
use quote::{quote, quote_spanned, ToTokens};
|
||||||
use syn::{LitInt, LitStr};
|
use syn::{LitInt, LitStr};
|
||||||
@ -29,6 +30,7 @@ impl Display {
|
|||||||
let mut variants = Vec::new();
|
let mut variants = Vec::new();
|
||||||
for variant in variant_vec {
|
for variant in variant_vec {
|
||||||
let mut display_value = variant.ident.to_string().to_token_stream();
|
let mut display_value = variant.ident.to_string().to_token_stream();
|
||||||
|
|
||||||
for attr in variant.attrs.iter() {
|
for attr in variant.attrs.iter() {
|
||||||
if !attr.path().is_ident("sea_orm") {
|
if !attr.path().is_ident("sea_orm") {
|
||||||
continue;
|
continue;
|
||||||
@ -40,6 +42,8 @@ impl Display {
|
|||||||
meta.value()?.parse::<LitInt>()?;
|
meta.value()?.parse::<LitInt>()?;
|
||||||
} else if meta.path.is_ident("display_value") {
|
} else if meta.path.is_ident("display_value") {
|
||||||
display_value = meta.value()?.parse::<LitStr>()?.to_token_stream();
|
display_value = meta.value()?.parse::<LitStr>()?.to_token_stream();
|
||||||
|
} else if meta.path.is_ident("rename") {
|
||||||
|
CaseStyle::try_from(&meta)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(meta.error(format!(
|
return Err(meta.error(format!(
|
||||||
"Unknown attribute parameter found: {:?}",
|
"Unknown attribute parameter found: {:?}",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::util::{escape_rust_keyword, trim_starting_raw_identifier};
|
use super::util::{escape_rust_keyword, trim_starting_raw_identifier};
|
||||||
|
use crate::strum::helpers::case_style::{CaseStyle, CaseStyleHelpers};
|
||||||
use heck::{ToSnakeCase, ToUpperCamelCase};
|
use heck::{ToSnakeCase, ToUpperCamelCase};
|
||||||
use proc_macro2::{Ident, Span, TokenStream};
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
@ -13,6 +14,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
let mut comment = quote! {None};
|
let mut comment = quote! {None};
|
||||||
let mut schema_name = quote! { None };
|
let mut schema_name = quote! { None };
|
||||||
let mut table_iden = false;
|
let mut table_iden = false;
|
||||||
|
let mut rename_all: Option<CaseStyle> = None;
|
||||||
|
|
||||||
attrs
|
attrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| attr.path().is_ident("sea_orm"))
|
.filter(|attr| attr.path().is_ident("sea_orm"))
|
||||||
@ -28,6 +31,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
schema_name = quote! { Some(#name) };
|
schema_name = quote! { Some(#name) };
|
||||||
} else if meta.path.is_ident("table_iden") {
|
} else if meta.path.is_ident("table_iden") {
|
||||||
table_iden = true;
|
table_iden = true;
|
||||||
|
} else if meta.path.is_ident("rename_all") {
|
||||||
|
rename_all = Some((&meta).try_into()?);
|
||||||
} else {
|
} else {
|
||||||
// Reads the value expression to advance the parse stream.
|
// Reads the value expression to advance the parse stream.
|
||||||
// Some parameters, such as `primary_key`, do not have any value,
|
// Some parameters, such as `primary_key`, do not have any value,
|
||||||
@ -38,6 +43,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let entity_def = table_name
|
let entity_def = table_name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|table_name| {
|
.map(|table_name| {
|
||||||
@ -106,7 +112,9 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
let mut ignore = false;
|
let mut ignore = false;
|
||||||
let mut unique = false;
|
let mut unique = false;
|
||||||
let mut sql_type = None;
|
let mut sql_type = None;
|
||||||
let mut column_name = if original_field_name
|
let mut column_name = if let Some(case_style) = rename_all {
|
||||||
|
Some(field_name.convert_case(Some(case_style)))
|
||||||
|
} else if original_field_name
|
||||||
!= original_field_name.to_upper_camel_case().to_snake_case()
|
!= original_field_name.to_upper_camel_case().to_snake_case()
|
||||||
{
|
{
|
||||||
// `to_snake_case` was used to trim prefix and tailing underscore
|
// `to_snake_case` was used to trim prefix and tailing underscore
|
||||||
@ -114,6 +122,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut enum_name = None;
|
let mut enum_name = None;
|
||||||
let mut is_primary_key = false;
|
let mut is_primary_key = false;
|
||||||
// search for #[sea_orm(primary_key, auto_increment = false, column_type = "String(Some(255))", default_value = "new user", default_expr = "gen_random_uuid()", column_name = "name", enum_name = "Name", nullable, indexed, unique)]
|
// search for #[sea_orm(primary_key, auto_increment = false, column_type = "String(Some(255))", default_value = "new user", default_expr = "gen_random_uuid()", column_name = "name", enum_name = "Name", nullable, indexed, unique)]
|
||||||
|
@ -2,6 +2,7 @@ use heck::{
|
|||||||
ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,
|
ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use syn::meta::ParseNestedMeta;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
Ident, LitStr,
|
Ident, LitStr,
|
||||||
@ -24,15 +25,15 @@ pub enum CaseStyle {
|
|||||||
|
|
||||||
const VALID_CASE_STYLES: &[&str] = &[
|
const VALID_CASE_STYLES: &[&str] = &[
|
||||||
"camelCase",
|
"camelCase",
|
||||||
"PascalCase",
|
|
||||||
"kebab-case",
|
"kebab-case",
|
||||||
"snake_case",
|
|
||||||
"SCREAMING_SNAKE_CASE",
|
|
||||||
"SCREAMING-KEBAB-CASE",
|
|
||||||
"lowercase",
|
|
||||||
"UPPERCASE",
|
|
||||||
"title_case",
|
|
||||||
"mixed_case",
|
"mixed_case",
|
||||||
|
"SCREAMING_SNAKE_CASE",
|
||||||
|
"snake_case",
|
||||||
|
"title_case",
|
||||||
|
"UPPERCASE",
|
||||||
|
"lowercase",
|
||||||
|
"SCREAMING-KEBAB-CASE",
|
||||||
|
"PascalCase",
|
||||||
];
|
];
|
||||||
|
|
||||||
impl Parse for CaseStyle {
|
impl Parse for CaseStyle {
|
||||||
@ -109,6 +110,21 @@ impl CaseStyleHelpers for Ident {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'meta> TryFrom<&ParseNestedMeta<'meta>> for CaseStyle {
|
||||||
|
type Error = syn::Error;
|
||||||
|
|
||||||
|
fn try_from(value: &ParseNestedMeta) -> Result<Self, Self::Error> {
|
||||||
|
let meta_string_literal: LitStr = value.value()?.parse()?;
|
||||||
|
let value_string = meta_string_literal.value();
|
||||||
|
match CaseStyle::from_str(value_string.as_str()) {
|
||||||
|
Ok(rule) => Ok(rule),
|
||||||
|
Err(()) => Err(value.error(format!(
|
||||||
|
"Unknown value for attribute parameter: `{value_string}`. Valid values are: `{VALID_CASE_STYLES:?}`"
|
||||||
|
))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_convert_case() {
|
fn test_convert_case() {
|
||||||
let id = Ident::new("test_me", proc_macro2::Span::call_site());
|
let id = Ident::new("test_me", proc_macro2::Span::call_site());
|
||||||
|
109
sea-orm-macros/tests/derive_active_enum_test.rs
Normal file
109
sea-orm-macros/tests/derive_active_enum_test.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
use sea_orm::ActiveEnum;
|
||||||
|
use sea_orm_macros::{DeriveActiveEnum, EnumIter};
|
||||||
|
|
||||||
|
#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]
|
||||||
|
#[sea_orm(
|
||||||
|
rs_type = "String",
|
||||||
|
db_type = "Enum",
|
||||||
|
enum_name = "test_enum",
|
||||||
|
rename_all = "camelCase"
|
||||||
|
)]
|
||||||
|
enum TestEnum {
|
||||||
|
DefaultVariant,
|
||||||
|
#[sea_orm(rename = "camelCase")]
|
||||||
|
VariantCamelCase,
|
||||||
|
#[sea_orm(rename = "kebab-case")]
|
||||||
|
VariantKebabCase,
|
||||||
|
#[sea_orm(rename = "mixed_case")]
|
||||||
|
VariantMixedCase,
|
||||||
|
#[sea_orm(rename = "SCREAMING_SNAKE_CASE")]
|
||||||
|
VariantShoutySnakeCase,
|
||||||
|
#[sea_orm(rename = "snake_case")]
|
||||||
|
VariantSnakeCase,
|
||||||
|
#[sea_orm(rename = "title_case")]
|
||||||
|
VariantTitleCase,
|
||||||
|
#[sea_orm(rename = "UPPERCASE")]
|
||||||
|
VariantUpperCase,
|
||||||
|
#[sea_orm(rename = "lowercase")]
|
||||||
|
VariantLowerCase,
|
||||||
|
#[sea_orm(rename = "SCREAMING-KEBAB-CASE")]
|
||||||
|
VariantScreamingKebabCase,
|
||||||
|
#[sea_orm(rename = "PascalCase")]
|
||||||
|
VariantPascalCase,
|
||||||
|
#[sea_orm(string_value = "CuStOmStRiNgVaLuE")]
|
||||||
|
CustomStringValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn derive_active_enum_value() {
|
||||||
|
assert_eq!(TestEnum::DefaultVariant.to_value(), "defaultVariant");
|
||||||
|
assert_eq!(TestEnum::VariantCamelCase.to_value(), "variantCamelCase");
|
||||||
|
assert_eq!(TestEnum::VariantKebabCase.to_value(), "variant-kebab-case");
|
||||||
|
assert_eq!(TestEnum::VariantMixedCase.to_value(), "variantMixedCase");
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::VariantShoutySnakeCase.to_value(),
|
||||||
|
"VARIANT_SHOUTY_SNAKE_CASE"
|
||||||
|
);
|
||||||
|
assert_eq!(TestEnum::VariantSnakeCase.to_value(), "variant_snake_case");
|
||||||
|
assert_eq!(TestEnum::VariantTitleCase.to_value(), "Variant Title Case");
|
||||||
|
assert_eq!(TestEnum::VariantUpperCase.to_value(), "VARIANTUPPERCASE");
|
||||||
|
assert_eq!(TestEnum::VariantLowerCase.to_value(), "variantlowercase");
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::VariantScreamingKebabCase.to_value(),
|
||||||
|
"VARIANT-SCREAMING-KEBAB-CASE"
|
||||||
|
);
|
||||||
|
assert_eq!(TestEnum::VariantPascalCase.to_value(), "VariantPascalCase");
|
||||||
|
assert_eq!(TestEnum::CustomStringValue.to_value(), "CuStOmStRiNgVaLuE");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn derive_active_enum_from_value() {
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"defaultVariant".to_string()),
|
||||||
|
Ok(TestEnum::DefaultVariant)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"variantCamelCase".to_string()),
|
||||||
|
Ok(TestEnum::VariantCamelCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"variant-kebab-case".to_string()),
|
||||||
|
Ok(TestEnum::VariantKebabCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"variantMixedCase".to_string()),
|
||||||
|
Ok(TestEnum::VariantMixedCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"VARIANT_SHOUTY_SNAKE_CASE".to_string()),
|
||||||
|
Ok(TestEnum::VariantShoutySnakeCase),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"variant_snake_case".to_string()),
|
||||||
|
Ok(TestEnum::VariantSnakeCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"Variant Title Case".to_string()),
|
||||||
|
Ok(TestEnum::VariantTitleCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"VARIANTUPPERCASE".to_string()),
|
||||||
|
Ok(TestEnum::VariantUpperCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"variantlowercase".to_string()),
|
||||||
|
Ok(TestEnum::VariantLowerCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"VARIANT-SCREAMING-KEBAB-CASE".to_string()),
|
||||||
|
Ok(TestEnum::VariantScreamingKebabCase),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"VariantPascalCase".to_string()),
|
||||||
|
Ok(TestEnum::VariantPascalCase)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
TestEnum::try_from_value(&"CuStOmStRiNgVaLuE".to_string()),
|
||||||
|
Ok(TestEnum::CustomStringValue)
|
||||||
|
);
|
||||||
|
}
|
40
sea-orm-macros/tests/derive_entity_model_column_name_test.rs
Normal file
40
sea-orm-macros/tests/derive_entity_model_column_name_test.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use sea_orm::prelude::*;
|
||||||
|
use sea_orm::Iden;
|
||||||
|
use sea_orm::Iterable;
|
||||||
|
use sea_orm_macros::DeriveEntityModel;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
|
#[sea_orm(table_name = "user")]
|
||||||
|
#[sea_orm(rename_all = "camelCase")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
id: i32,
|
||||||
|
username: String,
|
||||||
|
first_name: String,
|
||||||
|
middle_name: String,
|
||||||
|
#[sea_orm(column_name = "lAsTnAmE")]
|
||||||
|
last_name: String,
|
||||||
|
orders_count: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_column_names() {
|
||||||
|
let columns: Vec<String> = Column::iter().map(|item| item.to_string()).collect();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
columns,
|
||||||
|
vec![
|
||||||
|
"id",
|
||||||
|
"username",
|
||||||
|
"firstName",
|
||||||
|
"middleName",
|
||||||
|
"lAsTnAmE",
|
||||||
|
"ordersCount",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user