naming_conventions/conventions/
pascal_case.rs1use crate::{conventions::to_no_case, tool, Convention};
2
3use regex::{Captures, Error, Regex};
4
5pub struct PascalCase;
6
7impl Convention for PascalCase {
8 fn to(&self, string: &str) -> Result<String, Error> {
9 to_pascal_case(string)
10 }
11
12 fn is(&self, string: &str) -> Result<bool, Error> {
13 is_pascal_case(string)
14 }
15}
16
17pub fn to_pascal_case(string: &str) -> Result<String, Error> {
18 let replacement =
19 |haystack: &str, caps: &Captures, _options: &Option<bool>| -> Result<String, Error> {
20 let m = caps.get(0).unwrap();
21 Ok(haystack[m.start()..m.end()].to_uppercase())
22 };
23
24 let no_case = to_no_case(&string)?.to_lowercase();
25
26 let mut haystack = String::from(" ");
27 haystack.push_str(&no_case);
28
29 let re = Regex::new(r"[^\w][a-z]").unwrap();
30 let result = tool::replace_all(&re, &haystack, replacement, &None)?;
31
32 let re = Regex::new(r"\s+").unwrap();
33 let result = re.replace_all(&result, "").to_string();
34
35 log::debug!(target: "convention::pascal_case::to_pascal_case", "'{}' changed to '{}' (pascal_case).", string, result);
36 Ok(result)
37}
38
39pub fn is_pascal_case(string: &str) -> Result<bool, Error> {
40 let pascal_case = to_pascal_case(string)?;
41 Ok(pascal_case == string)
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 fn init() {
49 dotenv::dotenv().ok();
50 let _ = env_logger::try_init();
51 }
52
53 #[test]
54 fn test_to_pascal_case() {
55 tests::init();
56
57 let result = to_pascal_case("vahid_Vakili ").unwrap();
58 assert_eq!(&result, "VahidVakili")
59 }
60
61 #[test]
62 fn test_is_pascal_case() {
63 tests::init();
64
65 let result = is_pascal_case("VahidVakili").unwrap();
66 assert_eq!(result, true);
67
68 let result = is_pascal_case("vahid_Vakili").unwrap();
69 assert_eq!(result, false);
70 }
71}