Skip to main content

ferrisup_common/
lib.rs

1//! Library template created with FerrisUp
2
3pub mod fs;
4pub mod cargo;
5
6
7/// Convert a string to PascalCase
8/// For example: "hello_world" -> "HelloWorld"
9pub fn to_pascal_case(input: &str) -> String {
10    input
11        .split('_')
12        .map(|word| {
13            if word.is_empty() {
14                String::new()
15            } else {
16                let mut chars = word.chars();
17                match chars.next() {
18                    None => String::new(),
19                    Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
20                }
21            }
22        })
23        .collect()
24}
25
26/// Convert a string to snake_case
27pub fn to_snake_case(s: &str) -> String {
28    if s.is_empty() {
29        return String::new();
30    }
31    
32    let mut result = String::new();
33    let mut last_was_underscore = false;
34    let chars: Vec<char> = s.chars().collect();
35    
36    // Handle the first character
37    if chars[0].is_alphanumeric() {
38        result.push(chars[0].to_ascii_lowercase());
39    } else {
40        last_was_underscore = true;
41    }
42    
43    // Process the rest of the characters
44    for i in 1..chars.len() {
45        let c = chars[i];
46        
47        if c.is_alphanumeric() {
48            // If current char is uppercase and previous char was lowercase or a number,
49            // add an underscore before it
50            if c.is_uppercase() && 
51               i > 0 && 
52               (chars[i-1].is_lowercase() || chars[i-1].is_numeric()) && 
53               !last_was_underscore {
54                result.push('_');
55            }
56            result.push(c.to_ascii_lowercase());
57            last_was_underscore = false;
58        } else if !last_was_underscore {
59            result.push('_');
60            last_was_underscore = true;
61        }
62    }
63    
64    // Remove trailing underscore if any
65    if result.ends_with('_') {
66        result.pop();
67    }
68    
69    result
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_to_pascal_case() {
78        // Basic snake_case to PascalCase conversion
79        assert_eq!(to_pascal_case("hello_world"), "HelloWorld");
80        
81        // Single word
82        assert_eq!(to_pascal_case("hello"), "Hello");
83        
84        // Multiple underscores
85        assert_eq!(to_pascal_case("hello_beautiful_world"), "HelloBeautifulWorld");
86        
87        // Already capitalized
88        assert_eq!(to_pascal_case("Hello_World"), "HelloWorld");
89        
90        // Empty string
91        assert_eq!(to_pascal_case(""), "");
92        
93        // String with leading underscore
94        assert_eq!(to_pascal_case("_hello"), "Hello");
95        
96        // String with trailing underscore
97        assert_eq!(to_pascal_case("hello_"), "Hello");
98        
99        // String with consecutive underscores
100        assert_eq!(to_pascal_case("hello__world"), "HelloWorld");
101        
102        // String with mixed case
103        assert_eq!(to_pascal_case("hello_World"), "HelloWorld");
104    }
105    
106    #[test]
107    fn test_to_snake_case() {
108        // PascalCase to snake_case conversion
109        assert_eq!(to_snake_case("HelloWorld"), "hello_world");
110        
111        // camelCase to snake_case conversion
112        assert_eq!(to_snake_case("helloWorld"), "hello_world");
113        
114        // Single word
115        assert_eq!(to_snake_case("Hello"), "hello");
116        
117        // Already snake_case
118        assert_eq!(to_snake_case("hello_world"), "hello_world");
119        
120        // Empty string
121        assert_eq!(to_snake_case(""), "");
122        
123        // String with spaces
124        assert_eq!(to_snake_case("Hello World"), "hello_world");
125        
126        // String with mixed punctuation
127        assert_eq!(to_snake_case("Hello, World!"), "hello_world");
128        
129        // String with consecutive non-alphanumeric characters
130        assert_eq!(to_snake_case("Hello--World"), "hello_world");
131        
132        // String with leading non-alphanumeric characters
133        assert_eq!(to_snake_case("-Hello"), "hello");
134        
135        // String with trailing non-alphanumeric characters
136        assert_eq!(to_snake_case("Hello-"), "hello");
137        
138        // Mixed case with numbers
139        assert_eq!(to_snake_case("Hello123World"), "hello123_world");
140        
141        // All caps
142        assert_eq!(to_snake_case("HELLO_WORLD"), "hello_world");
143    }
144}