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
89
90
91
use std::fs;
use std::io::ErrorKind;
use std::path::Path;
pub fn move_directory_contents(
src_dir: impl AsRef<Path>,
dst_dir: impl AsRef<Path>,
) -> Result<(), std::io::Error> {
for dir_entry in fs::read_dir(src_dir.as_ref())? {
let dir_entry = dir_entry?;
let relative_path = pathdiff::diff_paths(dir_entry.path(), src_dir.as_ref())
.ok_or_else(|| std::io::Error::new(ErrorKind::Other, "std::fs::read_dir unexpectedly returned an entry that is not in the directory that was read."))?;
fs::rename(dir_entry.path(), dst_dir.as_ref().join(relative_path))?;
}
Ok(())
}
#[cfg(test)]
mod test {
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use tempfile::tempdir;
use super::*;
#[test]
fn test() {
let src_dir = tempdir().unwrap();
let dst_dir = tempdir().unwrap();
let mut test_data = HashMap::new();
test_data.insert(PathBuf::from("foo"), String::from("foo"));
test_data.insert(PathBuf::from("bar"), String::from("bar"));
test_data.insert(PathBuf::from("baz"), String::from("baz"));
test_data.insert(
PathBuf::from("subdir").join("foo"),
String::from("foosubdir"),
);
test_data.insert(
PathBuf::from("subdir")
.join("more")
.join("more")
.join("file.txt"),
String::from("Hello World!"),
);
for (path, contents) in &test_data {
if let Some(parent_dir) = path.parent() {
fs::create_dir_all(src_dir.path().join(parent_dir)).unwrap();
}
fs::write(src_dir.path().join(path), contents).unwrap();
}
move_directory_contents(&src_dir, &dst_dir).unwrap();
for (path, expected_contents) in &test_data {
let actual_contents = fs::read_to_string(dst_dir.path().join(path)).unwrap();
assert_eq!(expected_contents, &actual_contents);
}
assert!(src_dir.path().exists());
assert!(fs::read_dir(src_dir.path()).unwrap().next().is_none());
}
}