1 use heck::{CamelCase, KebabCase, MixedCase, ShoutySnakeCase, SnakeCase, TitleCase};
2
3 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4 pub enum CaseStyle {
5 CamelCase,
6 KebabCase,
7 MixedCase,
8 ShoutySnakeCase,
9 SnakeCase,
10 TitleCase,
11 UpperCase,
12 LowerCase,
13 ScreamingKebabCase,
14 PascalCase,
15 }
16
17 impl<'s> From<&'s str> for CaseStyle {
from(text: &'s str) -> CaseStyle18 fn from(text: &'s str) -> CaseStyle {
19 match text {
20 "camel_case" | "PascalCase" => CaseStyle::PascalCase,
21 "camelCase" => CaseStyle::CamelCase,
22 "snake_case" | "snek_case" => CaseStyle::SnakeCase,
23 "kebab_case" | "kebab-case" => CaseStyle::KebabCase,
24 "SCREAMING-KEBAB-CASE" => CaseStyle::ScreamingKebabCase,
25 "shouty_snake_case" | "shouty_snek_case" | "SCREAMING_SNAKE_CASE" => {
26 CaseStyle::ShoutySnakeCase
27 }
28 "title_case" => CaseStyle::TitleCase,
29 "mixed_case" => CaseStyle::MixedCase,
30 "lowercase" => CaseStyle::LowerCase,
31 "UPPERCASE" => CaseStyle::UpperCase,
32 _ => panic!(
33 "Unexpected case style for serialize_all: `{}`. Valid values are: `{:?}`",
34 text,
35 [
36 "camelCase",
37 "PascalCase",
38 "kebab-case",
39 "snake_case",
40 "SCREAMING_SNAKE_CASE",
41 "SCREAMING-KEBAB-CASE",
42 "lowercase",
43 "UPPERCASE",
44 "title_case",
45 "mixed_case",
46 ]
47 ),
48 }
49 }
50 }
51
52 pub trait CaseStyleHelpers {
convert_case(&self, case_style: Option<CaseStyle>) -> String53 fn convert_case(&self, case_style: Option<CaseStyle>) -> String;
54 }
55
56 impl CaseStyleHelpers for syn::Ident {
convert_case(&self, case_style: Option<CaseStyle>) -> String57 fn convert_case(&self, case_style: Option<CaseStyle>) -> String {
58 let ident_string = self.to_string();
59 if let Some(case_style) = case_style {
60 match case_style {
61 CaseStyle::PascalCase => ident_string.to_camel_case(),
62 CaseStyle::KebabCase => ident_string.to_kebab_case(),
63 CaseStyle::MixedCase => ident_string.to_mixed_case(),
64 CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),
65 CaseStyle::SnakeCase => ident_string.to_snake_case(),
66 CaseStyle::TitleCase => ident_string.to_title_case(),
67 CaseStyle::UpperCase => ident_string.to_uppercase(),
68 CaseStyle::LowerCase => ident_string.to_lowercase(),
69 CaseStyle::ScreamingKebabCase => ident_string.to_kebab_case().to_uppercase(),
70 CaseStyle::CamelCase => {
71 let camel_case = ident_string.to_camel_case();
72 let mut pascal = String::with_capacity(camel_case.len());
73 let mut it = camel_case.chars();
74 if let Some(ch) = it.next() {
75 pascal.extend(ch.to_lowercase());
76 }
77 pascal.extend(it);
78 pascal
79 }
80 }
81 } else {
82 ident_string
83 }
84 }
85 }
86
87 #[test]
test_convert_case()88 fn test_convert_case() {
89 let id = syn::Ident::new("test_me", proc_macro2::Span::call_site());
90 assert_eq!("testMe", id.convert_case(Some(CaseStyle::CamelCase)));
91 assert_eq!("TestMe", id.convert_case(Some(CaseStyle::PascalCase)));
92 }
93