1use crate::consts::{SNAKE_JOIN, WORD_SEPARATORS};
4
5pub fn words(name: &str) -> Vec<&str> {
9 let mut out = Vec::new();
10 for part in name.split(WORD_SEPARATORS).filter(|p| !p.is_empty()) {
11 let mut start = 0;
12 for (i, c) in part.char_indices().skip(1) {
13 if c.is_uppercase() {
14 out.push(&part[start..i]);
15 start = i;
16 }
17 }
18 out.push(&part[start..]);
19 }
20 out
21}
22
23fn capitalized(word: &str) -> String {
25 let mut chars = word.chars();
26 chars
27 .next()
28 .map(|first| first.to_uppercase().collect::<String>() + chars.as_str())
29 .unwrap_or_default()
30}
31
32pub fn pascal(name: &str) -> String {
34 words(name).into_iter().map(capitalized).collect()
35}
36
37pub fn camel(name: &str) -> String {
39 let pascal = pascal(name);
40 let mut chars = pascal.chars();
41 chars
42 .next()
43 .map(|first| first.to_lowercase().collect::<String>() + chars.as_str())
44 .unwrap_or_default()
45}
46
47pub fn snake(name: &str) -> String {
49 joined_lower(name).join(SNAKE_JOIN)
50}
51
52pub fn screaming(name: &str) -> String {
54 snake(name).to_uppercase()
55}
56
57fn joined_lower(name: &str) -> Vec<String> {
58 words(name).into_iter().map(str::to_lowercase).collect()
59}
60
61#[cfg(test)]
62mod tests;