1#[cfg(feature = "alloc")]
6#[doc(inline)]
7pub use self::utils::*;
8
9#[derive(
10 Clone,
11 Copy,
12 Debug,
13 Default,
14 Eq,
15 Hash,
16 Ord,
17 PartialEq,
18 PartialOrd,
19 strum::AsRefStr,
20 strum::Display,
21 strum::EnumCount,
22 strum::EnumIs,
23 strum::EnumIter,
24 strum::EnumString,
25 strum::VariantArray,
26 strum::VariantNames,
27)]
28#[cfg_attr(
29 feature = "serde",
30 derive(serde::Deserialize, serde::Serialize,),
31 serde(rename_all = "snake_case")
32)]
33#[strum(serialize_all = "snake_case")]
34pub enum CaseType {
35 CamelCase,
36 KebabCase,
37 PascalCase,
38 #[default]
39 SnakeCase,
40}
41
42#[cfg(feature = "alloc")]
43impl CaseType {
44 pub fn convert(&self, s: &str) -> alloc::string::String {
46 match self {
47 Self::CamelCase => utils::to_camelcase(s),
48 Self::KebabCase => utils::to_kebabcase(s),
49 Self::PascalCase => utils::to_pascalcase(s),
50 Self::SnakeCase => utils::to_snakecase(s),
51 }
52 }
53}
54
55#[cfg(feature = "alloc")]
56mod utils {
57 use alloc::string::String;
58
59 pub fn to_snakecase(s: &str) -> String {
61 s.chars()
62 .fold(String::new(), |mut acc, c| {
63 if c.is_uppercase() {
64 if !acc.is_empty() {
65 acc.push('_');
66 }
67 acc.push(c.to_lowercase().next().unwrap());
68 } else {
69 acc.push(c);
70 }
71 acc
72 })
73 .to_lowercase()
74 }
75
76 pub fn to_camelcase(s: &str) -> String {
78 let mut chars = s.chars();
79 let first = chars.next().unwrap();
80 let rest = chars.collect::<String>();
81 format!("{}{}", first.to_lowercase(), rest)
82 }
83
84 pub fn to_pascalcase(s: &str) -> String {
86 let mut chars = s.chars();
87 let first = chars.next().unwrap();
88 let rest = chars.collect::<String>();
89 format!("{}{}", first.to_uppercase(), rest)
90 }
91
92 pub fn to_kebabcase(s: &str) -> String {
94 s.chars()
95 .fold(String::new(), |mut acc, c| {
96 if c.is_uppercase() {
97 if !acc.is_empty() {
98 acc.push('-');
99 }
100 acc.push(c.to_lowercase().next().unwrap());
101 } else {
102 acc.push(c);
103 }
104 acc
105 })
106 .to_lowercase()
107 }
108
109 pub fn to_screaming_snakecase(s: &str) -> String {
111 s.chars().fold(String::new(), |mut acc, c| {
112 if c.is_uppercase() {
113 if !acc.is_empty() {
114 acc.push('_');
115 }
116 acc.push(c);
117 } else {
118 acc.push(c.to_uppercase().next().unwrap());
119 }
120 acc
121 })
122 }
123}