@@ -66,11 +66,21 @@ impl Inflector for TailInflector {
66
66
fn decompose ( s : & str ) -> Vec < String > {
67
67
let mut out: Vec < Vec < char > > = vec ! [ vec![ ] ] ;
68
68
for c in s. chars ( ) {
69
- if c. is_whitespace ( ) || c == '-' || c == '_' || c == ':' {
69
+ // Non-ASCII alphanumeric characters, such as whitespace, dashes,
70
+ // underscores, or non-ASCII characters, are presumed to always be
71
+ // delimiters.
72
+ if !c. is_ascii_alphanumeric ( ) {
70
73
out. push ( vec ! [ ] ) ;
71
74
continue ;
72
75
}
73
76
77
+ // Do not allow a part to start with a digit. Most languages prohibit
78
+ // digits at the beginning of identifiers. Just ignore the digit to make
79
+ // this happen.
80
+ if c. is_ascii_digit ( ) && out. last ( ) . unwrap ( ) . is_empty ( ) {
81
+ continue ;
82
+ }
83
+
74
84
if let Some ( last_char) = out. last ( ) . unwrap ( ) . last ( ) {
75
85
if last_char. is_lowercase ( ) && c. is_uppercase ( ) {
76
86
out. push ( vec ! [ ] ) ;
@@ -154,13 +164,17 @@ impl Case {
154
164
}
155
165
156
166
pub fn inflect ( & self , words : & [ String ] ) -> String {
157
- if words. is_empty ( ) {
158
- return "" . to_owned ( ) ;
167
+ let mut word_parts: Vec < _ > = words. into_iter ( ) . flat_map ( |word| decompose ( word) ) . collect ( ) ;
168
+
169
+ // If after decomposing the word into its parts (and after the
170
+ // associated stripping of non-ASCII alphanumerics) we don't have any
171
+ // words to work with, then inflect a "default name" instead.
172
+ if word_parts. is_empty ( ) {
173
+ word_parts = vec ! [ "default" . into( ) , "name" . into( ) ] ;
159
174
}
160
175
161
- let parts: Vec < _ > = words
176
+ let parts: Vec < _ > = word_parts
162
177
. into_iter ( )
163
- . flat_map ( |word| decompose ( word) )
164
178
. enumerate ( )
165
179
. map ( |( i, word) | {
166
180
if self . initialisms . contains ( & word) {
@@ -245,7 +259,7 @@ mod tests {
245
259
246
260
#[ test]
247
261
fn test_camel_case ( ) {
248
- assert_eq ! ( "" , Case :: camel_case( ) . inflect( & [ ] ) ) ;
262
+ assert_eq ! ( "defaultName " , Case :: camel_case( ) . inflect( & [ ] ) ) ;
249
263
250
264
assert_eq ! ( "foo" , Case :: camel_case( ) . inflect( & [ "foo" . to_owned( ) ] ) ) ;
251
265
assert_eq ! (
@@ -260,7 +274,7 @@ mod tests {
260
274
261
275
#[ test]
262
276
fn test_pascal_case ( ) {
263
- assert_eq ! ( "" , Case :: pascal_case( ) . inflect( & [ ] ) ) ;
277
+ assert_eq ! ( "DefaultName " , Case :: pascal_case( ) . inflect( & [ ] ) ) ;
264
278
265
279
assert_eq ! ( "Foo" , Case :: pascal_case( ) . inflect( & [ "foo" . to_owned( ) ] ) ) ;
266
280
assert_eq ! (
@@ -275,7 +289,7 @@ mod tests {
275
289
276
290
#[ test]
277
291
fn test_snake_case ( ) {
278
- assert_eq ! ( "" , Case :: snake_case( ) . inflect( & [ ] ) ) ;
292
+ assert_eq ! ( "default_name " , Case :: snake_case( ) . inflect( & [ ] ) ) ;
279
293
280
294
assert_eq ! ( "foo" , Case :: snake_case( ) . inflect( & [ "foo" . to_owned( ) ] ) ) ;
281
295
assert_eq ! (
@@ -290,7 +304,7 @@ mod tests {
290
304
291
305
#[ test]
292
306
fn test_screaming_snake_case ( ) {
293
- assert_eq ! ( "" , Case :: screaming_snake_case( ) . inflect( & [ ] ) ) ;
307
+ assert_eq ! ( "DEFAULT_NAME " , Case :: screaming_snake_case( ) . inflect( & [ ] ) ) ;
294
308
295
309
assert_eq ! (
296
310
"FOO" ,
0 commit comments