-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.rs
72 lines (67 loc) · 1.93 KB
/
util.rs
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
use std::error::Error;
use std::fs::{copy, create_dir_all};
use std::path::{Component, Path, PathBuf};
use rand::Rng;
// stolen from https://github.com/rust-lang/rfcs/issues/2208#issuecomment-342679694
pub fn normalize(p: &Path) -> PathBuf {
let mut stack: Vec<Component> = Vec::new();
for component in p.components() {
match component {
Component::CurDir => {}
Component::ParentDir => {
let top = stack.last().cloned();
match top {
Some(c) => {
match c {
Component::Prefix(_) => { stack.push(component); }
Component::RootDir => {}
Component::CurDir => { unreachable!(); }
Component::ParentDir => { stack.push(component); }
Component::Normal(_) => { let _ = stack.pop(); }
}
}
None => { stack.push(component); }
}
}
_ => { stack.push(component); }
}
}
if stack.is_empty() { return PathBuf::from(Component::CurDir.as_os_str()); }
let mut norm_path = PathBuf::new();
for item in &stack { norm_path.push(item.as_os_str()); }
norm_path
}
pub fn rand_str(size: usize) -> String {
let mut rng = rand::thread_rng();
(0..size).map(|_| rng.gen_range('a'..='z')).collect()
}
pub fn find_available_name(dir: impl AsRef<Path>) -> PathBuf {
let dir = dir.as_ref();
for len in 1..32usize {
for _ in 0..10 {
let path = dir.join(rand_str(len));
if !path.exists() {
return path;
}
}
}
panic!("Did you flooded shm folder?")
}
pub fn copy_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<(), Box<dyn Error>> {
let src = src.as_ref();
let dst = dst.as_ref();
for ent in (src.read_dir()?).flatten() {
let dst_path = dst.join(ent.file_name());
// skip if destination already existed
if dst_path.exists() {
continue;
}
if ent.metadata()?.is_dir() {
copy_all(src.join(ent.file_name()), dst_path)?;
} else {
if let Ok(true) = dst.try_exists() {} else { create_dir_all(dst)?; }
copy(src.join(ent.file_name()), dst_path)?;
}
}
Ok(())
}