vika_cli/generator/
utils.rs

1pub fn to_pascal_case(s: &str) -> String {
2    let mut result = String::new();
3    let mut capitalize_next = true;
4
5    for c in s.chars() {
6        if c == '_' || c == '-' || c == ' ' {
7            capitalize_next = true;
8        } else if capitalize_next {
9            result.push(c.to_uppercase().next().unwrap_or(c));
10            capitalize_next = false;
11        } else {
12            result.push(c);
13        }
14    }
15
16    result
17}
18
19pub fn to_camel_case(s: &str) -> String {
20    let pascal = to_pascal_case(s);
21    if pascal.is_empty() {
22        return pascal;
23    }
24
25    let mut chars = pascal.chars();
26    let first = chars.next().unwrap().to_lowercase().next().unwrap();
27    format!("{}{}", first, chars.as_str())
28}
29
30/// Sanitizes a property name to be a valid JavaScript identifier
31/// Returns the original name if valid, or the name in quotes if invalid
32pub fn sanitize_property_name(name: &str) -> String {
33    let first_char = name.chars().next();
34    let needs_quotes = match first_char {
35        Some(c) if c.is_ascii_digit() => true, // starts with number
36        _ => name.contains(' ') || name.contains('-') && !name.starts_with('-'), // contains spaces or hyphens (but not negative numbers)
37    };
38
39    if needs_quotes {
40        format!("\"{}\"", name)
41    } else {
42        name.to_string()
43    }
44}
45
46/// Sanitizes module names for use as directory/file names
47/// Replaces spaces with hyphens and removes other invalid characters
48pub fn sanitize_module_name(name: &str) -> String {
49    name.replace(' ', "-")
50        .chars()
51        .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '_' || *c == '/')
52        .collect()
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_to_pascal_case_simple() {
61        assert_eq!(to_pascal_case("hello"), "Hello");
62        assert_eq!(to_pascal_case("world"), "World");
63    }
64
65    #[test]
66    fn test_to_pascal_case_with_underscore() {
67        assert_eq!(to_pascal_case("hello_world"), "HelloWorld");
68        assert_eq!(to_pascal_case("user_name"), "UserName");
69    }
70
71    #[test]
72    fn test_to_pascal_case_with_hyphen() {
73        assert_eq!(to_pascal_case("hello-world"), "HelloWorld");
74        assert_eq!(to_pascal_case("api-key"), "ApiKey");
75    }
76
77    #[test]
78    fn test_to_pascal_case_with_space() {
79        assert_eq!(to_pascal_case("hello world"), "HelloWorld");
80        assert_eq!(to_pascal_case("user name"), "UserName");
81    }
82
83    #[test]
84    fn test_to_pascal_case_mixed() {
85        assert_eq!(to_pascal_case("hello_world-test"), "HelloWorldTest");
86        assert_eq!(to_pascal_case("api_key-name"), "ApiKeyName");
87    }
88
89    #[test]
90    fn test_to_pascal_case_empty() {
91        assert_eq!(to_pascal_case(""), "");
92    }
93
94    #[test]
95    fn test_to_pascal_case_single_word() {
96        assert_eq!(to_pascal_case("test"), "Test");
97    }
98
99    #[test]
100    fn test_to_camel_case_simple() {
101        assert_eq!(to_camel_case("hello"), "hello");
102        assert_eq!(to_camel_case("world"), "world");
103    }
104
105    #[test]
106    fn test_to_camel_case_with_underscore() {
107        assert_eq!(to_camel_case("hello_world"), "helloWorld");
108        assert_eq!(to_camel_case("user_name"), "userName");
109    }
110
111    #[test]
112    fn test_to_camel_case_with_hyphen() {
113        assert_eq!(to_camel_case("hello-world"), "helloWorld");
114        assert_eq!(to_camel_case("api-key"), "apiKey");
115    }
116
117    #[test]
118    fn test_to_camel_case_empty() {
119        assert_eq!(to_camel_case(""), "");
120    }
121
122    #[test]
123    fn test_to_camel_case_single_word() {
124        assert_eq!(to_camel_case("test"), "test");
125    }
126
127    #[test]
128    fn test_to_camel_case_mixed() {
129        assert_eq!(to_camel_case("hello_world-test"), "helloWorldTest");
130    }
131
132    #[test]
133    fn test_sanitize_property_name_valid() {
134        assert_eq!(sanitize_property_name("name"), "name");
135        assert_eq!(sanitize_property_name("userName"), "userName");
136        assert_eq!(sanitize_property_name("_private"), "_private");
137    }
138
139    #[test]
140    fn test_sanitize_property_name_starts_with_number() {
141        assert_eq!(sanitize_property_name("2xl"), "\"2xl\"");
142        assert_eq!(sanitize_property_name("3xl"), "\"3xl\"");
143        assert_eq!(sanitize_property_name("404error"), "\"404error\"");
144    }
145
146    #[test]
147    fn test_sanitize_property_name_with_spaces() {
148        assert_eq!(
149            sanitize_property_name("Translation name"),
150            "\"Translation name\""
151        );
152        assert_eq!(sanitize_property_name("user name"), "\"user name\"");
153    }
154
155    #[test]
156    fn test_sanitize_module_name() {
157        assert_eq!(sanitize_module_name("cart"), "cart");
158        assert_eq!(sanitize_module_name("AI Chat"), "AI-Chat");
159        assert_eq!(sanitize_module_name("admin/orders"), "admin/orders");
160        assert_eq!(sanitize_module_name("test module name"), "test-module-name");
161    }
162}