11// This file is part of Astarte.
22//
3- // Copyright 2023 - 2025 SECO Mind Srl
3+ // Copyright 2023-2026 SECO Mind Srl
44//
55// Licensed under the Apache License, Version 2.0 (the "License");
66// you may not use this file except in compliance with the License.
1616//
1717// SPDX-License-Identifier: Apache-2.0
1818
19- use std:: {
20- borrow:: Cow ,
21- fmt:: { self , Debug , Display } ,
22- } ;
19+ use std:: fmt:: Debug ;
20+
21+ use darling:: FromMeta ;
2322
2423/// The different possible ways to change case of fields in a struct.
25- #[ derive( Debug , Copy , Clone , PartialEq , Default ) ]
24+ #[ derive( Debug , Copy , Clone , PartialEq , FromMeta ) ]
2625pub enum RenameRule {
27- /// Do not rename.
28- #[ default]
29- None ,
3026 /// Rename to "lowercase" style.
31- LowerCase ,
27+ #[ darling( rename = "lowercase" ) ]
28+ Lower ,
3229 /// Rename to "UPPERCASE" style.
33- UpperCase ,
30+ #[ darling( rename = "UPPERCASE" ) ]
31+ Upper ,
3432 /// Rename to "PascalCase" style.
35- PascalCase ,
33+ #[ darling( rename = "PascalCase" ) ]
34+ Pascal ,
3635 /// Rename to "camelCase" style.
37- CamelCase ,
36+ #[ darling( rename = "camelCase" ) ]
37+ Camel ,
3838 /// Rename to "snake_case" style.
39- SnakeCase ,
39+ #[ darling( rename = "snake_case" ) ]
40+ Snake ,
4041 /// Rename to "SCREAMING_SNAKE_CASE" style.
41- ScreamingSnakeCase ,
42+ #[ darling( rename = "SCREAMING_SNAKE_CASE" ) ]
43+ ScreamingSnake ,
4244 /// Rename to "kebab-case" style.
43- KebabCase ,
45+ #[ darling( rename = "kebab-case" ) ]
46+ Kebab ,
4447 /// Rename to "SCREAMING-KEBAB-CASE" style.
45- ScreamingKebabCase ,
48+ #[ darling( rename = "SCREAMING-KEBAB-CASE" ) ]
49+ ScreamingKebab ,
4650}
4751
48- static RENAME_RULES : & [ ( & str , RenameRule ) ] = & [
49- ( "lowercase" , RenameRule :: LowerCase ) ,
50- ( "UPPERCASE" , RenameRule :: UpperCase ) ,
51- ( "PascalCase" , RenameRule :: PascalCase ) ,
52- ( "camelCase" , RenameRule :: CamelCase ) ,
53- ( "snake_case" , RenameRule :: SnakeCase ) ,
54- ( "SCREAMING_SNAKE_CASE" , RenameRule :: ScreamingSnakeCase ) ,
55- ( "kebab-case" , RenameRule :: KebabCase ) ,
56- ( "SCREAMING-KEBAB-CASE" , RenameRule :: ScreamingKebabCase ) ,
57- ] ;
58-
5952impl RenameRule {
60- /// Obrain a rename rule from a str
61- pub fn from_str ( rename_all_str : & str ) -> Result < Self , ParseError < ' _ > > {
62- for ( name, rule) in RENAME_RULES {
63- if rename_all_str == * name {
64- return Ok ( * rule) ;
65- }
66- }
67- Err ( ParseError {
68- unknown : rename_all_str,
69- } )
70- }
71-
7253 /// Apply a renaming rule to a struct field, returning the version expected in the source.
73- pub fn apply_to_field < ' a > ( & self , field : & ' a str ) -> Cow < ' a , str > {
74- match * self {
75- RenameRule :: None => Cow :: Borrowed ( field) ,
76- RenameRule :: LowerCase | RenameRule :: SnakeCase => field. to_ascii_lowercase ( ) . into ( ) ,
77- RenameRule :: UpperCase => field. to_ascii_uppercase ( ) . into ( ) ,
78- RenameRule :: PascalCase => {
54+ pub fn apply_to_field ( & self , field : & str ) -> String {
55+ match self {
56+ RenameRule :: Lower | RenameRule :: Snake => field. to_ascii_lowercase ( ) ,
57+ RenameRule :: Upper => field. to_ascii_uppercase ( ) ,
58+ RenameRule :: Pascal => {
7959 let mut pascal = String :: new ( ) ;
8060 let mut capitalize = true ;
61+
8162 for ch in field. chars ( ) {
8263 if ch == '_' {
8364 capitalize = true ;
@@ -88,39 +69,20 @@ impl RenameRule {
8869 pascal. push ( ch) ;
8970 }
9071 }
91- Cow :: Owned ( pascal)
92- }
93- RenameRule :: CamelCase => {
94- let pascal = RenameRule :: PascalCase . apply_to_field ( field) ;
95- Cow :: Owned ( pascal[ ..1 ] . to_ascii_lowercase ( ) + & pascal[ 1 ..] )
96- }
97- RenameRule :: ScreamingSnakeCase => field. to_ascii_uppercase ( ) . into ( ) ,
98- RenameRule :: KebabCase => field. replace ( '_' , "-" ) . into ( ) ,
99- RenameRule :: ScreamingKebabCase => RenameRule :: ScreamingSnakeCase
100- . apply_to_field ( field)
101- . replace ( '_' , "-" )
102- . into ( ) ,
103- }
104- }
105- }
10672
107- # [ derive ( Debug ) ]
108- pub struct ParseError < ' a > {
109- unknown : & ' a str ,
110- }
73+ pascal
74+ }
75+ RenameRule :: Camel => {
76+ let pascal = RenameRule :: Pascal . apply_to_field ( field ) ;
11177
112- impl Display for ParseError < ' _ > {
113- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
114- f. write_str ( "unknown rename rule `rename_all = " ) ?;
115- Debug :: fmt ( self . unknown , f) ?;
116- f. write_str ( "`, expected one of " ) ?;
117- for ( i, ( name, _rule) ) in RENAME_RULES . iter ( ) . enumerate ( ) {
118- if i > 0 {
119- f. write_str ( ", " ) ?;
78+ pascal[ ..1 ] . to_ascii_lowercase ( ) + & pascal[ 1 ..]
12079 }
121- Debug :: fmt ( name, f) ?;
80+ RenameRule :: ScreamingSnake => field. to_ascii_uppercase ( ) ,
81+ RenameRule :: Kebab => field. replace ( '_' , "-" ) ,
82+ RenameRule :: ScreamingKebab => RenameRule :: ScreamingSnake
83+ . apply_to_field ( field)
84+ . replace ( '_' , "-" ) ,
12285 }
123- Ok ( ( ) )
12486 }
12587}
12688
@@ -146,18 +108,17 @@ mod test {
146108 ( "a" , "A" , "A" , "a" , "A" , "a" , "A" ) ,
147109 ( "z42" , "Z42" , "Z42" , "z42" , "Z42" , "z42" , "Z42" ) ,
148110 ] {
149- assert_eq ! ( RenameRule :: None . apply_to_field( original) , original) ;
150- assert_eq ! ( RenameRule :: UpperCase . apply_to_field( original) , upper) ;
151- assert_eq ! ( RenameRule :: PascalCase . apply_to_field( original) , pascal) ;
152- assert_eq ! ( RenameRule :: CamelCase . apply_to_field( original) , camel) ;
153- assert_eq ! ( RenameRule :: SnakeCase . apply_to_field( original) , original) ;
111+ assert_eq ! ( RenameRule :: Upper . apply_to_field( original) , upper) ;
112+ assert_eq ! ( RenameRule :: Pascal . apply_to_field( original) , pascal) ;
113+ assert_eq ! ( RenameRule :: Camel . apply_to_field( original) , camel) ;
114+ assert_eq ! ( RenameRule :: Snake . apply_to_field( original) , original) ;
154115 assert_eq ! (
155- RenameRule :: ScreamingSnakeCase . apply_to_field( original) ,
116+ RenameRule :: ScreamingSnake . apply_to_field( original) ,
156117 screaming
157118 ) ;
158- assert_eq ! ( RenameRule :: KebabCase . apply_to_field( original) , kebab) ;
119+ assert_eq ! ( RenameRule :: Kebab . apply_to_field( original) , kebab) ;
159120 assert_eq ! (
160- RenameRule :: ScreamingKebabCase . apply_to_field( original) ,
121+ RenameRule :: ScreamingKebab . apply_to_field( original) ,
161122 screaming_kebab
162123 ) ;
163124 }
0 commit comments