Skip to main content

winisland_plugin_api/packager/
packaging.rs

1use std::io::Write;
2use std::path::Path;
3
4/// Create a ZIP archive containing all files under `source_dir`.
5pub fn create_zip(source_dir: &Path, output_path: &Path) -> Result<(), String> {
6    let file = std::fs::File::create(output_path)
7        .map_err(|e| format!("Cannot create ZIP '{}': {}", output_path.display(), e))?;
8    let mut zip = zip::ZipWriter::new(file);
9
10    let options = zip::write::FileOptions::<()>::default()
11        .compression_method(zip::CompressionMethod::Deflated);
12
13    add_dir(&mut zip, source_dir, source_dir, &options)?;
14
15    zip.finish()
16        .map_err(|e| format!("Cannot finalise ZIP: {}", e))?;
17    Ok(())
18}
19
20fn add_dir(
21    zip: &mut zip::ZipWriter<std::fs::File>,
22    base: &Path,
23    dir: &Path,
24    options: &zip::write::FileOptions<()>,
25) -> Result<(), String> {
26    for entry in std::fs::read_dir(dir).map_err(|e| format!("Cannot read dir: {}", e))? {
27        let entry = entry.map_err(|e| format!("Dir entry error: {}", e))?;
28        let path = entry.path();
29        let relative = path
30            .strip_prefix(base)
31            .map_err(|_| "Path prefix error".to_string())?;
32
33        if entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
34            let name = relative.to_string_lossy().replace('\\', "/") + "/";
35            zip.add_directory(&name, *options)
36                .map_err(|e| format!("Cannot add dir '{}': {}", name, e))?;
37            add_dir(zip, base, &path, options)?;
38        } else {
39            let name = relative.to_string_lossy().replace('\\', "/");
40            zip.start_file(&name, *options)
41                .map_err(|e| format!("Cannot add file '{}': {}", name, e))?;
42            let data = std::fs::read(&path)
43                .map_err(|e| format!("Cannot read '{}': {}", path.display(), e))?;
44            zip.write_all(&data)
45                .map_err(|e| format!("Cannot write '{}': {}", name, e))?;
46        }
47    }
48    Ok(())
49}