use std::fs::File;
use std::io::prelude::*;
use std::io::{Seek, Write};
use std::iter::Iterator;
use std::path::Path;
use walkdir::{DirEntry, WalkDir};
use zip::result::ZipError;
use zip::write::FileOptions;
fn zip_dir<T>(
it: &mut dyn Iterator<Item = DirEntry>,
prefix: &str,
writer: T,
) -> zip::result::ZipResult<()>
where
T: Write + Seek,
{
let mut zip = zip::ZipWriter::new(writer);
let mut options = FileOptions::default()
.compression_method(zip::CompressionMethod::Zstd)
.unix_permissions(0o755);
if let Ok(v) = std::env::var("COMPRESS") {
if v == "1" {
options = options.compression_level(Some(22));
}
}
let mut buffer = Vec::new();
for entry in it {
let path = entry.path();
let name = path.strip_prefix(Path::new(prefix)).unwrap();
if path.is_file() {
println!("adding file {path:?} as {name:?} ...");
#[allow(deprecated)]
zip.start_file_from_path(name, options)?;
let mut f = File::open(path)?;
f.read_to_end(&mut buffer)?;
zip.write_all(&buffer)?;
buffer.clear();
} else if !name.as_os_str().is_empty() {
println!("adding dir {path:?} as {name:?} ...");
#[allow(deprecated)]
zip.add_directory_from_path(name, options)?;
}
}
zip.finish()?;
Result::Ok(())
}
fn main() -> Result<(), ZipError> {
let _ = std::fs::remove_dir_all("target/out");
let walkdir = WalkDir::new("assets");
let it = walkdir.into_iter();
println!("cargo:rerun-if-changed=assets/");
println!("cargo:rerun-if-changed=build.rs");
zip_dir(
&mut it.filter_map(|e| e.ok()),
"assets",
File::create(std::env::var("OUT_DIR").unwrap() + "/asset").unwrap(),
)
}