this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(zip): add --level compression level support

+57 -15
+57 -15
src/backends/zip.rs
··· 1 - use crate::utils::{CmprssInput, CmprssOutput, CommonArgs, Compressor, ExtractedTarget, Result}; 1 + use crate::utils::{ 2 + CmprssInput, CmprssOutput, CommonArgs, CompressionLevelValidator, Compressor, 3 + DefaultCompressionValidator, ExtractedTarget, LevelArgs, Result, 4 + }; 2 5 use anyhow::bail; 3 6 use clap::Args; 4 7 use std::fs::File; ··· 13 16 pub struct ZipArgs { 14 17 #[clap(flatten)] 15 18 pub common_args: CommonArgs, 19 + 20 + #[clap(flatten)] 21 + pub level_args: LevelArgs, 16 22 } 17 23 18 - #[derive(Default, Clone)] 19 - pub struct Zip {} 24 + #[derive(Clone)] 25 + pub struct Zip { 26 + pub compression_level: i32, 27 + } 28 + 29 + impl Default for Zip { 30 + fn default() -> Self { 31 + Zip { 32 + compression_level: DefaultCompressionValidator.default_level(), 33 + } 34 + } 35 + } 20 36 21 37 impl Zip { 22 - pub fn new(_args: &ZipArgs) -> Zip { 23 - Zip {} 38 + pub fn new(args: &ZipArgs) -> Zip { 39 + Zip { 40 + compression_level: args.level_args.resolve(&DefaultCompressionValidator), 41 + } 42 + } 43 + 44 + fn file_options(&self) -> FileOptions<'static, ()> { 45 + FileOptions::<()>::default() 46 + .compression_method(CompressionMethod::Deflated) 47 + .compression_level(Some(self.compression_level as i64)) 24 48 } 25 49 26 50 fn compress_to_file<W: Write + Seek>(&self, input: CmprssInput, writer: W) -> Result { 27 51 let mut zip_writer = ZipWriter::new(writer); 28 - let options = FileOptions::<()>::default().compression_method(CompressionMethod::Deflated); 52 + let options = self.file_options(); 29 53 30 54 match input { 31 55 CmprssInput::Path(paths) => { ··· 38 62 } else if path.is_dir() { 39 63 // Use the directory as the base and add its contents 40 64 let base = path.parent().unwrap_or(&path); 41 - add_directory(&mut zip_writer, base, &path)?; 65 + add_directory(&mut zip_writer, base, &path, options)?; 42 66 } else { 43 67 bail!("zip does not support this file type"); 44 68 } ··· 201 225 } 202 226 } 203 227 204 - fn add_directory<W: Write + Seek>(zip: &mut ZipWriter<W>, base: &Path, path: &Path) -> Result { 228 + fn add_directory<W: Write + Seek>( 229 + zip: &mut ZipWriter<W>, 230 + base: &Path, 231 + path: &Path, 232 + options: FileOptions<'static, ()>, 233 + ) -> Result { 205 234 for entry in std::fs::read_dir(path)? { 206 235 let entry = entry?; 207 236 let entry_path = entry.path(); ··· 212 241 .to_string_lossy() 213 242 .replace('\\', "/"); 214 243 if entry_path.is_file() { 215 - let options = 216 - FileOptions::<()>::default().compression_method(CompressionMethod::Deflated); 217 244 zip.start_file(name, options)?; 218 245 let mut f = File::open(&entry_path)?; 219 246 io::copy(&mut f, zip)?; 220 247 } else if entry_path.is_dir() { 221 248 // Ensure directory entry ends with '/' 222 249 let dir_name = name.clone() + "/"; 223 - zip.add_directory( 224 - dir_name, 225 - FileOptions::<()>::default().compression_method(CompressionMethod::Deflated), 226 - )?; 227 - add_directory(zip, base, &entry_path)?; 250 + zip.add_directory(dir_name, options)?; 251 + add_directory(zip, base, &entry_path, options)?; 228 252 } 229 253 } 230 254 Ok(()) ··· 250 274 fn test_zip_default_compression() -> Result { 251 275 let compressor = Zip::default(); 252 276 test_compression(&compressor) 277 + } 278 + 279 + /// Test fast compression level 280 + #[test] 281 + fn test_zip_fast_compression() -> Result { 282 + let fast_compressor = Zip { 283 + compression_level: 1, 284 + }; 285 + test_compression(&fast_compressor) 286 + } 287 + 288 + /// Test best compression level 289 + #[test] 290 + fn test_zip_best_compression() -> Result { 291 + let best_compressor = Zip { 292 + compression_level: 9, 293 + }; 294 + test_compression(&best_compressor) 253 295 } 254 296 255 297 /// Test zip-specific functionality: directory handling