1use std::{io::Write, path::Path};
5
6mod zip_dir;
7
8#[derive(thiserror::Error, Debug)]
9pub enum Error {
10 #[error("IO error: {source}")]
11 IoError {
12 #[from]
13 source: std::io::Error,
14 },
15 #[error("zip error: {source}")]
16 ZipError {
17 #[from]
18 source: zip::result::ZipError,
19 },
20}
21
22pub fn dir_to_braidz<P1: AsRef<Path>, P2: AsRef<Path>>(
24 output_dirname: P1,
25 output_zipfile: P2,
26) -> Result<(), Error> {
27 let mut file = std::fs::File::create(&output_zipfile)?;
28
29 let header = "BRAIDZ file. This is a standard ZIP file with a \
30 specific schema. You can view the contents of this \
31 file at https://braidz.strawlab.org/\n";
32 file.write_all(header.as_bytes())?;
33
34 let walkdir = walkdir::WalkDir::new(&output_dirname);
35
36 let mut readme_entry: Option<walkdir::DirEntry> = None;
40
41 let mut files = Vec::new();
42 for entry in walkdir.into_iter().filter_map(|e| e.ok()) {
43 if entry.file_name() == braid_types::README_MD_FNAME {
44 readme_entry = Some(entry);
45 } else {
46 files.push(entry);
47 }
48 }
49 if let Some(entry) = readme_entry {
50 files.insert(0, entry);
51 }
52
53 let mut zipw = zip::ZipWriter::new(file);
54 let options = zip::write::SimpleFileOptions::default()
63 .compression_method(zip::CompressionMethod::Stored)
64 .large_file(true)
65 .unix_permissions(0o755);
66
67 zip_dir::zip_dir(&mut files.into_iter(), &output_dirname, &mut zipw, options)?;
68 zipw.finish()?;
69 Ok(())
70}