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
use std::{
fs::File,
io::{Seek, Write},
path::Path,
};
use crate::*;
pub fn compress(src: impl AsRef<Path>, dest: impl Write + Seek) -> Result<(), Error> {
let mut z = SevenZWriter::new(dest)?;
let parent = if src.as_ref().is_dir() {
src.as_ref()
} else {
src.as_ref().parent().unwrap_or(src.as_ref())
};
compress_path(src.as_ref(), parent, &mut z)?;
z.finish().map_err(Error::io)
}
pub fn compress_to_path(src: impl AsRef<Path>, dest: impl AsRef<Path>) -> Result<(), Error> {
if let Some(p) = dest.as_ref().parent() {
if !p.exists() {
std::fs::create_dir_all(p)
.map_err(|e| Error::io_msg(e, format!("Create dir failed:{:?}", dest.as_ref())))?;
}
}
compress(
src,
File::create(dest.as_ref())
.map_err(|e| Error::file_open(e, dest.as_ref().to_string_lossy().to_string()))?,
)
}
fn compress_path<W: Write + Seek, P: AsRef<Path>>(
src: P,
root: &Path,
z: &mut SevenZWriter<W>,
) -> Result<(), Error> {
let entry_name = src
.as_ref()
.strip_prefix(root)
.map_err(|e| Error::other(e.to_string()))?
.to_string_lossy()
.to_string();
let entry = SevenZWriter::<W>::create_archive_entry(src.as_ref(), entry_name);
let path = src.as_ref();
if path.is_dir() {
for dir in path
.read_dir()
.map_err(|e| Error::io_msg(e, "error read dir"))?
{
let dir = dir.map_err(Error::io)?;
let ftype = dir.file_type().map_err(Error::io)?;
if ftype.is_dir() || ftype.is_file() {
compress_path(dir.path(), root, z)?;
}
}
} else {
z.push_archive_entry(
entry,
Some(
File::open(path)
.map_err(|e| Error::file_open(e, path.to_string_lossy().to_string()))?,
),
)?;
}
Ok(())
}