@@ -1584,7 +1584,7 @@ fn render_enum(
15841584 lines. push ( format ! ( "#[derive({})]" , derives. join( ", " ) ) ) ;
15851585 lines. push ( format ! (
15861586 "#[serde(rename_all = \" {}\" )]" ,
1587- config . enum_naming_case ( ) . serde_rename_all ( )
1587+ enum_serde_rename_all ( values , config )
15881588 ) ) ;
15891589
15901590 match values {
@@ -1605,8 +1605,9 @@ fn render_enum(
16051605
16061606 match values {
16071607 EnumValues :: String ( string_values) => {
1608+ let use_screaming_snake_variants = uses_screaming_snake_variants ( string_values) ;
16081609 for s in string_values {
1609- let variant_name = enum_variant_name ( s ) ;
1610+ let variant_name = enum_string_variant_name ( s , use_screaming_snake_variants ) ;
16101611 lines. push ( format ! ( " #[sea_orm(string_value = \" {}\" )]" , s) ) ;
16111612 lines. push ( format ! ( " {}," , variant_name) ) ;
16121613 }
@@ -1631,6 +1632,20 @@ fn render_enum(
16311632fn enum_variant_name ( s : & str ) -> String {
16321633 let pascal = to_pascal_case ( s) ;
16331634
1635+ finalize_enum_variant_name ( pascal)
1636+ }
1637+
1638+ fn enum_string_variant_name ( s : & str , use_screaming_snake_variants : bool ) -> String {
1639+ let pascal = if use_screaming_snake_variants {
1640+ screaming_snake_to_pascal_case ( s)
1641+ } else {
1642+ to_pascal_case ( s)
1643+ } ;
1644+
1645+ finalize_enum_variant_name ( pascal)
1646+ }
1647+
1648+ fn finalize_enum_variant_name ( pascal : String ) -> String {
16341649 // Handle empty string
16351650 if pascal. is_empty ( ) {
16361651 return "Value" . to_string ( ) ;
@@ -1649,6 +1664,58 @@ fn enum_variant_name(s: &str) -> String {
16491664 pascal
16501665}
16511666
1667+ fn enum_serde_rename_all ( values : & EnumValues , config : & SeaOrmConfig ) -> & ' static str {
1668+ match values {
1669+ EnumValues :: String ( string_values) if uses_screaming_snake_variants ( string_values) => {
1670+ "SCREAMING_SNAKE_CASE"
1671+ }
1672+ _ => config. enum_naming_case ( ) . serde_rename_all ( ) ,
1673+ }
1674+ }
1675+
1676+ fn uses_screaming_snake_variants ( values : & [ String ] ) -> bool {
1677+ !values. is_empty ( ) && values. iter ( ) . all ( |value| is_screaming_snake_value ( value) )
1678+ }
1679+
1680+ fn is_screaming_snake_value ( value : & str ) -> bool {
1681+ let mut has_ascii_upper = false ;
1682+
1683+ for ch in value. chars ( ) {
1684+ if ch. is_ascii_lowercase ( ) {
1685+ return false ;
1686+ }
1687+ if ch. is_ascii_uppercase ( ) {
1688+ has_ascii_upper = true ;
1689+ continue ;
1690+ }
1691+ if ch. is_ascii_digit ( ) || ch == '_' {
1692+ continue ;
1693+ }
1694+ return false ;
1695+ }
1696+
1697+ has_ascii_upper
1698+ }
1699+
1700+ fn screaming_snake_to_pascal_case ( value : & str ) -> String {
1701+ value
1702+ . split ( '_' )
1703+ . filter ( |segment| !segment. is_empty ( ) )
1704+ . map ( |segment| {
1705+ let mut chars = segment. chars ( ) ;
1706+ match chars. next ( ) {
1707+ Some ( first) => {
1708+ let mut out = String :: new ( ) ;
1709+ out. push ( first. to_ascii_uppercase ( ) ) ;
1710+ out. extend ( chars. map ( |ch| ch. to_ascii_lowercase ( ) ) ) ;
1711+ out
1712+ }
1713+ None => String :: new ( ) ,
1714+ }
1715+ } )
1716+ . collect ( )
1717+ }
1718+
16521719fn to_pascal_case ( s : & str ) -> String {
16531720 let mut result = String :: new ( ) ;
16541721 let mut capitalize = true ;
@@ -2182,6 +2249,8 @@ mod helper_tests {
21822249 #[ case( "pending" , "Pending" ) ]
21832250 #[ case( "in_stock" , "InStock" ) ]
21842251 #[ case( "info-level" , "InfoLevel" ) ]
2252+ #[ case( "ACTIVE" , "ACTIVE" ) ]
2253+ #[ case( "ERROR_LEVEL" , "ERRORLEVEL" ) ]
21852254 #[ case( "1critical" , "N1critical" ) ]
21862255 #[ case( "123abc" , "N123abc" ) ]
21872256 #[ case( "1_critical" , "N1Critical" ) ]
@@ -2190,6 +2259,20 @@ mod helper_tests {
21902259 assert_eq ! ( enum_variant_name( input) , expected) ;
21912260 }
21922261
2262+ #[ test]
2263+ fn test_render_enum_uses_screaming_snake_serde_for_uppercase_values ( ) {
2264+ let mut lines = Vec :: new ( ) ;
2265+ let config = SeaOrmConfig :: default ( ) ;
2266+ let values = EnumValues :: String ( vec ! [ "PENDING" . into( ) , "IN_PROGRESS" . into( ) ] ) ;
2267+
2268+ render_enum ( & mut lines, "orders" , "order_status" , & values, & config) ;
2269+
2270+ let result = lines. join ( "\n " ) ;
2271+ assert ! ( result. contains( "#[serde(rename_all = \" SCREAMING_SNAKE_CASE\" )]" ) ) ;
2272+ assert ! ( result. contains( " #[sea_orm(string_value = \" PENDING\" )]\n Pending," ) ) ;
2273+ assert ! ( result. contains( " #[sea_orm(string_value = \" IN_PROGRESS\" )]\n InProgress," ) ) ;
2274+ }
2275+
21932276 fn string_enum_order_status ( ) -> ( & ' static str , EnumValues ) {
21942277 (
21952278 "order_status" ,
0 commit comments