use std::io::prelude::*; use zip::write::FileOptions; use walkdir::WalkDir; use std::path::Path; use std::fs::File; extern crate zip; extern crate walkdir; fn main() { std::process::exit(real_main()); } const METHOD_STORED : Option = Some(zip::CompressionMethod::Stored); #[cfg(feature = "flate2")] const METHOD_DEFLATED : Option = Some(zip::CompressionMethod::Deflated); #[cfg(not(feature = "flate2"))] const METHOD_DEFLATED : Option = None; #[cfg(feature = "bzip2")] const METHOD_BZIP2 : Option = Some(zip::CompressionMethod::Bzip2); #[cfg(not(feature = "bzip2"))] const METHOD_BZIP2 : Option = None; fn real_main() -> i32 { let args: Vec<_> = std::env::args().collect(); if args.len() < 3 { println!("Usage: {} ", args[0]); return 1; } let src_dir = &*args[1]; let dst_file = &*args[2]; for &method in [METHOD_STORED, METHOD_DEFLATED, METHOD_BZIP2].iter() { if method.is_none() { continue } match doit(src_dir, dst_file, method.unwrap()) { Ok(_) => println!("done: {} written to {}", src_dir, dst_file), Err(e) => println!("Error: {:?}", e), } } return 0; } fn doit(src_dir: &str, dst_file: &str, method: zip::CompressionMethod) -> zip::result::ZipResult<()> { if !Path::new(src_dir).is_dir() { return Ok(()); } let path = Path::new(dst_file); let file = File::create(&path).unwrap(); let mut zip = zip::ZipWriter::new(file); let options = FileOptions::default() .compression_method(method) .unix_permissions(0o755); let walkdir = WalkDir::new(src_dir.to_string()); let it = walkdir.into_iter(); for dent in it.filter_map(|e| e.ok()) { let path = dent.path(); let name = path.strip_prefix(Path::new(src_dir)) .unwrap() .to_str() .unwrap(); if path.is_file() { println!("adding {:?} as {:?} ...", path, name); try!(zip.start_file(name, options)); let mut f = File::open(path)?; let mut buffer = Vec::new(); f.read_to_end(&mut buffer)?; try!(zip.write_all(&*buffer)); } } try!(zip.finish()); Ok(()) }