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
use super::*;
pub trait ReadTree {
type E: Entry;
type I: Iterator<Item = Result<Self::E>>;
type R: std::io::Read;
fn iter_entries(&self) -> Result<Self::I>;
fn file_contents(&self, entry: &Self::E) -> Result<Self::R>;
}
pub trait WriteTree {
fn finish(&mut self) -> Result<()>;
fn write_dir(&mut self, entry: &Entry) -> Result<()>;
fn write_symlink(&mut self, entry: &Entry) -> Result<()>;
fn write_file(&mut self, entry: &Entry, content: &mut std::io::Read) -> Result<()>;
}
pub fn copy_tree<ST: ReadTree, DT: WriteTree>(
source: &ST, dest: &mut DT) -> Result<()> {
for entry in source.iter_entries()? {
let entry = entry?;
match entry.kind() {
Kind::Dir => dest.write_dir(&entry),
Kind::File => dest.write_file(&entry, &mut source.file_contents(&entry)?),
Kind::Symlink => dest.write_symlink(&entry),
Kind::Unknown => {
warn!("Skipping unsupported file kind of {}", &entry.apath());
continue;
}
}?;
}
dest.finish()
}