snake_case_rename/
punct.rs

1use lazy_static::lazy_static;
2use regex::Regex;
3
4use crate::result::Result;
5use std::collections::VecDeque;
6use std::{fs, fs::DirEntry};
7
8lazy_static! {
9    pub static ref PUNCT: Regex = Regex::new(r#"[[:punct:]]"#).unwrap();
10}
11
12pub fn replace_punct_with_underscore(name: &str) -> String {
13    let mut back = VecDeque::<char>::new();
14    let mut front = VecDeque::<char>::new();
15    let mut front_flag = false;
16    let mut back_flag = false;
17    let mut double_back_flag = false;
18    let mut double_front_flag = false;
19    let len = name.len();
20    let mut count = len - 1;
21    let mid = len / 2;
22    for i in 0..mid {
23        let b = name.as_bytes()[i] as char;
24        let f = name.as_bytes()[count] as char;
25        if PUNCT.is_match(&b.to_string()) || b == ' ' {
26            if back_flag && !double_back_flag {
27                back.push_back('_');
28                double_back_flag = true;
29            }
30        } else {
31            back.push_back(b);
32            back_flag = true;
33            double_back_flag = false;
34        }
35        if PUNCT.is_match(&f.to_string()) || f == ' ' {
36            if front_flag && !double_front_flag && back.len() > 1 {
37                front.push_front('_');
38                double_front_flag = true;
39            }
40        } else {
41            front.push_front(f);
42            front_flag = true;
43            double_front_flag = false;
44        }
45        count -= 1;
46    }
47    if len % 2 != 0 {
48        let f = name.as_bytes()[mid] as char;
49        if PUNCT.is_match(&f.to_string()) || f == ' '{
50            if  back.len() > 1 {
51                back.push_back('_');
52            }
53        } else {
54            back.push_back(f);
55        }
56    }
57    let mut out = back.iter().collect::<String>();
58    out.push_str(&front.iter().collect::<String>());
59    out
60}
61
62pub fn read_current_dir() -> Result<Vec<DirEntry>> {
63    let files = fs::read_dir(".")?;
64    Ok(files.into_iter().map(|f| f.unwrap()).collect())
65}
66
67pub fn snake_case_convert(s: String) -> String {
68    let mut buf = Vec::<char>::new();
69    let mut cc = 0;
70    for (i, c) in s.chars().into_iter().enumerate() {
71        if c.is_uppercase() && i > 0 {
72            if let Some(s) = buf.get(i - 1 + cc) {
73                if s.is_lowercase() && *s != '_' {
74                    buf.push('_');
75                    cc += 1;
76                }
77            }
78        }
79        buf.push(c);
80    }
81    buf.iter().collect::<String>().to_lowercase()
82}
83
84#[cfg(test)]
85pub mod tests {
86    use crate::punct::*;
87    #[test]
88    pub fn replace_punct_with_underscore_test_1() {
89        let name_input = "book-eng$algo";
90        let name_output = replace_punct_with_underscore(name_input);
91        assert_eq!("book_eng_algo", name_output);
92    }
93
94    #[test]
95    pub fn replace_punct_with_underscore_test_2() {
96        let name_input = "book-eng--- algo";
97        let name_output = replace_punct_with_underscore(name_input);
98        assert_eq!("book_eng_algo", name_output);
99    }
100
101    #[test]
102    pub fn replace_punct_with_underscore_test_3() {
103        let name_input = "book-!eng!algo";
104        let name_output = replace_punct_with_underscore(name_input);
105        assert_eq!("book_eng_algo", name_output);
106    }
107
108    #[test]
109    pub fn replace_punct_with_underscore_test_4() {
110        let name_input = "book())eng_algo";
111        let name_output = replace_punct_with_underscore(name_input);
112        assert_eq!("book_eng_algo", name_output);
113    }
114
115    #[test]
116    pub fn replace_punct_with_underscore_test_5() {
117        let name_input = "book_eng_algo";
118        let name_output = replace_punct_with_underscore(name_input);
119        assert_eq!("book_eng_algo", name_output);
120    }
121
122    #[test]
123    pub fn replace_punct_with_underscore_test_6() {
124        let name_input = " @!book@__eng_algo@!";
125        let name_output = replace_punct_with_underscore(name_input);
126        assert_eq!("book_eng_algo", name_output);
127    }
128
129    #[test]
130    pub fn replace_punct_with_underscore_test_7() {
131        let name_input = "book_eng_algo!@";
132        let name_output = replace_punct_with_underscore(name_input);
133        assert_eq!("book_eng_algo", name_output);
134    }
135
136    #[test]
137    pub fn replace_punct_with_underscore_test_8() {
138        let name_input = "book_eng_algo*&^";
139        let name_output = replace_punct_with_underscore(name_input);
140        assert_eq!("book_eng_algo", name_output);
141    }
142
143    #[test]
144    pub fn replace_punct_with_underscore_test_9() {
145        let name_input = "book_eng_algo   *&";
146        let name_output = replace_punct_with_underscore(name_input);
147        assert_eq!("book_eng_algo", name_output);
148    }
149
150    #[test]
151    pub fn replace_punct_with_underscore_test_10() {
152        let name_input = "  book_eng_algo  -";
153        let name_output = replace_punct_with_underscore(name_input);
154        assert_eq!("book_eng_algo", name_output);
155    }
156
157    #[test]
158    pub fn replace_punct_with_underscore_test_11() {
159        let name_input = "foo$bar";
160        let name_output = replace_punct_with_underscore(name_input);
161        assert_eq!("foo_bar", name_output);
162    }
163
164    #[test]
165    pub fn replace_punct_with_underscore_test_12() {
166        let name_input = "@@@@@foo";
167        let name_output = replace_punct_with_underscore(name_input);
168        assert_eq!("foo", name_output);
169    }
170
171    #[test]
172    pub fn snake_case_test1() {
173        let name_input = "fooBar".to_string();
174        let name_output = snake_case_convert(name_input);
175        assert_eq!("foo_bar", name_output);
176    }
177
178    #[test]
179    pub fn snake_case_test2() {
180        let name_input = "fooBarBAZR".to_string();
181        let name_output = snake_case_convert(name_input);
182        assert_eq!("foo_bar_bazr", name_output);
183    }
184
185    #[test]
186    pub fn snake_case_test3() {
187        let name_input = "fooBAR".to_string();
188        let name_output = snake_case_convert(name_input);
189        assert_eq!("foo_bar", name_output);
190    }
191
192    #[test]
193    pub fn snake_case_test4() {
194        let name_input = "fooBar".to_string();
195        let name_output = snake_case_convert(name_input);
196        assert_eq!("foo_bar", name_output);
197    }
198
199    #[test]
200    pub fn snake_case_test5() {
201        let name_input = "fooBAr".to_string();
202        let name_output = snake_case_convert(name_input);
203        assert_eq!("foo_bar", name_output);
204    }
205
206    #[test]
207    pub fn snake_case_test6() {
208        let name_input = "Foo".to_string();
209        let name_output = snake_case_convert(name_input);
210        assert_eq!("foo", name_output);
211    }
212}