teaql_tool_extra/
archive.rs1use teaql_tool_core::{Result, TeaQLToolError};
2use std::fs::File;
3use zip::write::SimpleFileOptions;
4
5#[derive(Debug, Clone)]
6pub struct ArchiveTool;
7
8impl ArchiveTool {
9 pub fn new() -> Self { Self }
10
11 pub fn zip_dir(&self, src_dir: &str, dst_file: &str) -> Result<()> {
12 let file = File::create(dst_file).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
13 let mut zip = zip::ZipWriter::new(file);
14 let options = SimpleFileOptions::default().compression_method(zip::CompressionMethod::Deflated);
15
16 let walkdir = walkdir::WalkDir::new(src_dir);
17 let it = walkdir.into_iter();
18
19 for entry in it.filter_map(|e| e.ok()) {
20 let path = entry.path();
21 let name = path.strip_prefix(std::path::Path::new(src_dir)).unwrap();
22 let name_str = name.to_str().unwrap().replace("\\", "/");
23
24 if path.is_file() {
25 zip.start_file(name_str, options).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
26 let mut f = File::open(path).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
27 std::io::copy(&mut f, &mut zip).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
28 } else if !name.as_os_str().is_empty() {
29 zip.add_directory(name_str, options).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
30 }
31 }
32 zip.finish().map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
33 Ok(())
34 }
35
36 pub fn unzip(&self, src_file: &str, dst_dir: &str) -> Result<()> {
37 let file = File::open(src_file).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
38 let mut archive = zip::ZipArchive::new(file).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
39
40 for i in 0..archive.len() {
41 let mut file = archive.by_index(i).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
42 let outpath = match file.enclosed_name() {
43 Some(path) => std::path::Path::new(dst_dir).join(path),
44 None => continue,
45 };
46
47 if (*file.name()).ends_with('/') {
48 std::fs::create_dir_all(&outpath).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
49 } else {
50 if let Some(p) = outpath.parent() {
51 if !p.exists() {
52 std::fs::create_dir_all(&p).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
53 }
54 }
55 let mut outfile = File::create(&outpath).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
56 std::io::copy(&mut file, &mut outfile).map_err(|e| TeaQLToolError::ExecutionError(e.to_string()))?;
57 }
58 }
59 Ok(())
60 }
61}
62
63impl Default for ArchiveTool {
64 fn default() -> Self { Self::new() }
65}