1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::fs;
use std::io;
use std::path::Path;
pub fn remove_empty_subdirs(dir: &Path) -> io::Result<()> {
_remove_empty_subdirs(dir, dir.clone())
}
fn _remove_empty_subdirs(dir: &Path, top_dir: &Path) -> io::Result<()> {
let entries = match fs::read_dir(dir) {
Ok(dirs) => dirs,
Err(err) => {
println!(
"Failed to read directory `{}` due to `{}`.",
dir.display(),
err.to_string()
);
return Ok(());
}
};
for entry in entries {
let path = entry.unwrap().path();
if path.is_dir() {
let is_hidden = path.file_name().unwrap().to_str().unwrap().starts_with('.');
if !is_hidden {
let can_stop = _try_to_remove_empty_dir(&path, &top_dir);
if !can_stop {
_remove_empty_subdirs(&path, &top_dir)?;
}
}
}
}
Ok(())
}
fn _try_to_remove_empty_dir(dir: &Path, top_dir: &Path) -> bool {
if dir == top_dir {
return true;
}
match fs::remove_dir(&dir) {
Ok(_) => {
println!("Empty directory `{}` is removed.", dir.display());
let parent_dir = dir.parent().unwrap();
_try_to_remove_empty_dir(&parent_dir, &top_dir);
true
}
Err(ref err) if err.kind() == io::ErrorKind::PermissionDenied => {
println!(
"Failed to remove directory `{}` due to Permission denied.",
dir.display()
);
true
}
Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
println!(
"Failed to remove directory `{}` due to Not found.",
dir.display()
);
true
}
Err(_err) => {
false
}
}
}