1use inflections::case;
2use inflections::Inflect;
3use inflector::string::pluralize::to_plural;
4use inflector::string::singularize::to_singular;
5
6mod deduped_vec;
7
8pub fn inflect_all(words: &Vec<String>) -> Vec<Vec<String>> {
9 inflect_ord(words).iter().flat_map(|ws| inflect_case(ws)).collect()
10}
11
12fn inflect_ord(words: &Vec<String>) -> Vec<Vec<String>> {
13 inflect_when_some_dont_match(
14 words,
15 vec![
16 (is_plural, to_plural),
17 (is_singular, to_singular),
26 ],
27 )
28}
29
30fn inflect_case(words: &Vec<String>) -> Vec<Vec<String>> {
31 inflect_when_some_dont_match(
32 words,
33 vec![
34 (case::is_camel_case, case::to_camel_case),
35 (case::is_pascal_case, case::to_pascal_case),
36 (case::is_kebab_case, case::to_kebab_case),
37 (case::is_train_case, case::to_train_case),
38 (case::is_snake_case, case::to_snake_case),
39 (case::is_constant_case, case::to_constant_case),
40 (is_all_lower, to_all_lower),
41 (is_all_upper, to_all_upper), ],
43 )
44}
45
46fn inflect_when_some_dont_match(
48 words: &Vec<String>,
49 preds_and_fns: Vec<(fn(&str) -> bool, fn(&str) -> String)>,
50) -> Vec<Vec<String>> {
51 let mut out = deduped_vec::DedupedVec::new();
52
53 out.push(words.clone());
54
55 for (pred, f) in preds_and_fns.iter() {
56 let all_match = words.iter().all(|w| pred(w));
57 if !all_match {
58 let mapped: Vec<String> = words.iter().map(|w| f(w)).collect();
59 out.push(mapped);
60 }
61 }
62
63 out.items
64}
65
66fn to_all_lower(word: &str) -> String {
67 word.to_camel_case().to_lowercase()
68}
69
70fn to_all_upper(word: &str) -> String {
71 word.to_camel_case().to_uppercase()
72}
73
74fn is_all_lower(word: &str) -> bool {
75 to_all_lower(word) == word
76}
77
78fn is_all_upper(word: &str) -> bool {
79 to_all_upper(word) == word
80}
81
82fn is_singular(word: &str) -> bool {
83 to_singular(word) == word
84}
85
86fn is_plural(word: &str) -> bool {
87 to_plural(word) == word
88}
89
90pub fn print_matrix(xxs: Vec<Vec<String>>) {
91 for xs in xxs {
92 println!("{}", xs.join(" "));
93 }
94}