diff --git a/Cargo.toml b/Cargo.toml index bb8179e1..3401e0a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ Library to support the reading and writing of zip files. """ [dependencies] -flate2 = { version = "1.0", default-features = false, features = ["rust_backend"]} +flate2 = { version = "1.0", default-features = false, features = ["rust_backend"], optional = true} time = "0.1" podio = "0.1" msdos_time = "0.1" @@ -22,4 +22,4 @@ bzip2 = { version = "0.3", optional = true } walkdir = "1.0" [features] -default = ["bzip2"] +default = ["bzip2", "flate2"] diff --git a/examples/write_dir.rs b/examples/write_dir.rs index e56094bc..d5940db0 100644 --- a/examples/write_dir.rs +++ b/examples/write_dir.rs @@ -12,6 +12,18 @@ 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 { @@ -22,15 +34,18 @@ fn real_main() -> i32 { let src_dir = &*args[1]; let dst_file = &*args[2]; - match doit(src_dir, dst_file) { - Ok(_) => println!("done: {} written to {}", src_dir, dst_file), - Err(e) => println!("Error: {:?}", e), + 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) -> zip::result::ZipResult<()> { +fn doit(src_dir: &str, dst_file: &str, method: zip::CompressionMethod) -> zip::result::ZipResult<()> { if !Path::new(src_dir).is_dir() { return Ok(()); } @@ -41,7 +56,7 @@ fn doit(src_dir: &str, dst_file: &str) -> zip::result::ZipResult<()> { let mut zip = zip::ZipWriter::new(file); let options = FileOptions::default() - .compression_method(zip::CompressionMethod::Deflated) + .compression_method(method) .unix_permissions(0o755); let walkdir = WalkDir::new(src_dir.to_string()); diff --git a/src/compression.rs b/src/compression.rs index bd772413..79c41a8f 100644 --- a/src/compression.rs +++ b/src/compression.rs @@ -9,6 +9,7 @@ pub enum CompressionMethod /// The file is stored (no compression) Stored, /// The file is Deflated + #[cfg(feature = "flate2")] Deflated, /// File is compressed using BZIP2 algorithm #[cfg(feature = "bzip2")] @@ -22,6 +23,7 @@ impl CompressionMethod { pub fn from_u16(val: u16) -> CompressionMethod { match val { 0 => CompressionMethod::Stored, + #[cfg(feature = "flate2")] 8 => CompressionMethod::Deflated, #[cfg(feature = "bzip2")] 12 => CompressionMethod::Bzip2, @@ -33,6 +35,7 @@ impl CompressionMethod { pub fn to_u16(self) -> u16 { match self { CompressionMethod::Stored => 0, + #[cfg(feature = "flate2")] CompressionMethod::Deflated => 8, #[cfg(feature = "bzip2")] CompressionMethod::Bzip2 => 12, @@ -62,16 +65,26 @@ mod test { } } - #[cfg(not(feature = "bzip2"))] + #[cfg(all(not(feature = "bzip2"), feature = "flate2"))] fn methods() -> Vec { vec![CompressionMethod::Stored, CompressionMethod::Deflated] } - #[cfg(feature = "bzip2")] + #[cfg(all(not(feature = "flate2"), feature = "bzip2"))] + fn methods() -> Vec { + vec![CompressionMethod::Stored, CompressionMethod::Bzip2] + } + + #[cfg(all(feature = "bzip2", feature = "flate2"))] fn methods() -> Vec { vec![CompressionMethod::Stored, CompressionMethod::Deflated, CompressionMethod::Bzip2] } + #[cfg(all(not(feature = "bzip2"), not(feature = "flate2")))] + fn methods() -> Vec { + vec![CompressionMethod::Stored] + } + #[test] fn to_eq_from() { fn check_match(method: CompressionMethod) { diff --git a/src/lib.rs b/src/lib.rs index 93e991c6..f694dfc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #[cfg(feature = "bzip2")] extern crate bzip2; +#[cfg(feature = "flate2")] extern crate flate2; extern crate msdos_time; extern crate podio; diff --git a/src/read.rs b/src/read.rs index 95df84ea..da29f40d 100644 --- a/src/read.rs +++ b/src/read.rs @@ -7,13 +7,17 @@ use result::{ZipResult, ZipError}; use std::io; use std::io::prelude::*; use std::collections::HashMap; -use flate2; -use flate2::read::DeflateDecoder; + use podio::{ReadPodExt, LittleEndian}; use types::{ZipFileData, System}; use cp437::FromCp437; use msdos_time::{TmMsDosExt, MsDosDateTime}; +#[cfg(feature = "flate2")] +use flate2; +#[cfg(feature = "flate2")] +use flate2::read::DeflateDecoder; + #[cfg(feature = "bzip2")] use bzip2::read::BzDecoder; @@ -59,6 +63,7 @@ pub struct ZipArchive enum ZipFileReader<'a> { Stored(Crc32Reader>), + #[cfg(feature = "flate2")] Deflated(Crc32Reader>>), #[cfg(feature = "bzip2")] Bzip2(Crc32Reader>>), @@ -235,6 +240,7 @@ impl ZipArchive limit_reader, data.crc32)) }, + #[cfg(feature = "flate2")] CompressionMethod::Deflated => { let deflate_reader = DeflateDecoder::new(limit_reader); @@ -377,6 +383,7 @@ impl<'a> ZipFile<'a> { fn get_reader(&mut self) -> &mut Read { match self.reader { ZipFileReader::Stored(ref mut r) => r as &mut Read, + #[cfg(feature = "flate2")] ZipFileReader::Deflated(ref mut r) => r as &mut Read, #[cfg(feature = "bzip2")] ZipFileReader::Bzip2(ref mut r) => r as &mut Read, diff --git a/src/write.rs b/src/write.rs index ce3bae54..7381e196 100644 --- a/src/write.rs +++ b/src/write.rs @@ -10,11 +10,14 @@ use std::io; use std::io::prelude::*; use std::mem; use time; -use flate2; -use flate2::write::DeflateEncoder; use podio::{WritePodExt, LittleEndian}; use msdos_time::TmMsDosExt; +#[cfg(feature = "flate2")] +use flate2; +#[cfg(feature = "flate2")] +use flate2::write::DeflateEncoder; + #[cfg(feature = "bzip2")] use bzip2; #[cfg(feature = "bzip2")] @@ -24,6 +27,7 @@ enum GenericZipWriter { Closed, Storer(W), + #[cfg(feature = "flate2")] Deflater(DeflateEncoder), #[cfg(feature = "bzip2")] Bzip2(BzEncoder), @@ -77,6 +81,7 @@ pub struct FileOptions { } impl FileOptions { + #[cfg(feature = "flate2")] /// Construct a new FileOptions object pub fn default() -> FileOptions { FileOptions { @@ -86,9 +91,21 @@ impl FileOptions { } } + #[cfg(not(feature = "flate2"))] + /// Construct a new FileOptions object + pub fn default() -> FileOptions { + FileOptions { + compression_method: CompressionMethod::Stored, + last_modified_time: time::now(), + permissions: None, + } + } + /// Set the compression method for the new file /// - /// The default is `CompressionMethod::Deflated` + /// The default is `CompressionMethod::Deflated`. If the deflate compression feature is + /// disabled, `CompressionMethod::Stored` becomes the default. + /// otherwise. pub fn compression_method(mut self, method: CompressionMethod) -> FileOptions { self.compression_method = method; self @@ -330,6 +347,7 @@ impl GenericZipWriter let bare = match mem::replace(self, GenericZipWriter::Closed) { GenericZipWriter::Storer(w) => w, + #[cfg(feature = "flate2")] GenericZipWriter::Deflater(w) => try!(w.finish()), #[cfg(feature = "bzip2")] GenericZipWriter::Bzip2(w) => try!(w.finish()), @@ -339,6 +357,7 @@ impl GenericZipWriter *self = match compression { CompressionMethod::Stored => GenericZipWriter::Storer(bare), + #[cfg(feature = "flate2")] CompressionMethod::Deflated => GenericZipWriter::Deflater(DeflateEncoder::new(bare, flate2::Compression::default())), #[cfg(feature = "bzip2")] CompressionMethod::Bzip2 => GenericZipWriter::Bzip2(BzEncoder::new(bare, bzip2::Compression::Default)), @@ -351,6 +370,7 @@ impl GenericZipWriter fn ref_mut(&mut self) -> Option<&mut Write> { match *self { GenericZipWriter::Storer(ref mut w) => Some(w as &mut Write), + #[cfg(feature = "flate2")] GenericZipWriter::Deflater(ref mut w) => Some(w as &mut Write), #[cfg(feature = "bzip2")] GenericZipWriter::Bzip2(ref mut w) => Some(w as &mut Write), @@ -379,6 +399,7 @@ impl GenericZipWriter fn current_compression(&self) -> Option { match *self { GenericZipWriter::Storer(..) => Some(CompressionMethod::Stored), + #[cfg(feature = "flate2")] GenericZipWriter::Deflater(..) => Some(CompressionMethod::Deflated), #[cfg(feature = "bzip2")] GenericZipWriter::Bzip2(..) => Some(CompressionMethod::Bzip2),