terminusdm/utils/
fs_utils.rs

1use std::path::PathBuf;
2
3pub fn get_available_filename(mut filename: PathBuf) -> PathBuf {
4    while filename.exists() {
5        let name_file = filename.file_stem().unwrap().to_string_lossy();
6
7        let ext = filename.extension().unwrap().to_string_lossy();
8
9        let new_name = if name_file.ends_with(')') {
10            let index_split = name_file.rfind('(').unwrap_or(name_file.len());
11            let (prefix, suffix) = name_file.split_at(index_split);
12
13            let new_suffix = match suffix
14                .trim_start_matches('(')
15                .trim_end_matches(')')
16                .parse::<u32>()
17            {
18                Ok(num) => (num + 1).to_string(),
19                Err(_) => "1".to_string(),
20            };
21
22            format!("{}({})", prefix, new_suffix)
23        } else {
24            format!("{name_file}(1)")
25        };
26
27        let new_filename = format!("{new_name}.{ext}",);
28        filename.set_file_name(new_filename);
29    }
30    filename
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_avail() {
39        let filename = PathBuf::from("test/test.txt");
40
41        let avail = get_available_filename(filename);
42        let expect_name = PathBuf::from("test/test(1).txt");
43
44        assert_eq!(expect_name, avail);
45    }
46
47    #[test]
48    fn test_avail_2() {
49        let filename = PathBuf::from("test/file.txt");
50
51        let avail = get_available_filename(filename);
52        let expect_name = PathBuf::from("test/file(4).txt");
53
54        assert_eq!(expect_name, avail);
55    }
56
57    #[test]
58    fn test_avail_3() {
59        let filename = PathBuf::from("test/nonexist.txt");
60
61        let avail = get_available_filename(filename);
62        let expect_name = PathBuf::from("test/nonexist.txt");
63
64        assert_eq!(expect_name, avail);
65    }
66}