1pub trait Case {
2 fn gen(splited_txt: Vec<String>) -> String;
3 fn parse(txt: &str) -> Vec<String>;
4}
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct SnakeCase;
8
9impl Case for SnakeCase {
10 fn gen(splited_txt: Vec<String>) -> String {
11 let mut result = String::new();
12
13 for (i, txt) in splited_txt.iter().enumerate() {
14 if i != 0 {
15 result.push('_');
16 }
17 for c in txt.chars() {
18 result.push_str(&c.to_lowercase().to_string());
19 }
20 }
21
22 result
23 }
24
25 fn parse(txt: &str) -> Vec<String> {
26 txt.split("_").map(|e| e.to_string()).collect::<Vec<_>>()
27 }
28}
29
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct CamelCase;
32
33impl Case for CamelCase {
34 fn gen(splited_txt: Vec<String>) -> String {
35 let mut result = String::new();
36
37 for (i, txt) in splited_txt.iter().enumerate() {
38 for (txt_i, c) in txt.char_indices() {
39 let c = if i != 0 && txt_i == 0 {
40 c.to_uppercase().to_string()
41 } else {
42 c.to_lowercase().to_string()
43 };
44 result.push_str(&c);
45 }
46 }
47
48 result
49 }
50
51 fn parse(txt: &str) -> Vec<String> {
52 let mut curr = String::new();
53 let mut result = Vec::new();
54
55 for c in txt.chars() {
56 if c.is_uppercase() {
57 result.push(curr.clone());
58 curr.clear();
59 }
60
61 curr.push(c);
62 }
63
64 if !curr.is_empty() {
65 result.push(curr.clone());
66 }
67
68 result
69 }
70}
71
72#[cfg(test)]
73mod test {
74 use crate::case::{CamelCase, Case, SnakeCase};
75
76 #[test]
77 fn snake_case_convert_test() {
78 let result = SnakeCase::gen(CamelCase::parse("thisIsATest"));
79 assert_eq!(result, "this_is_a_test");
80 }
81
82 #[test]
83 fn camel_case_convert_test() {
84 let result = CamelCase::gen(SnakeCase::parse("this_is_a_test"));
85 assert_eq!(result, "thisIsATest");
86 }
87}