this repo has no description
0
fork

Configure Feed

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

refactor(compressor): move clone_boxed to blanket helper trait

Replaces the per-backend fn clone_boxed stub with a CompressorClone
supertrait providing a blanket impl for any Compressor + Clone + 'static.
Clone itself can't be a Compressor supertrait (breaks dyn object safety),
but this keeps the same clone_boxed call sites while deleting ~50 lines
of identical boilerplate across 12 backends. Pipeline gets a manual
Clone impl since Vec<Box<dyn Compressor>> isn't auto-derivable.

+27 -65
-4
src/backends/brotli.rs
··· 88 88 "brotli" 89 89 } 90 90 91 - fn clone_boxed(&self) -> Box<dyn Compressor> { 92 - Box::new(self.clone()) 93 - } 94 - 95 91 /// Compress an input file or pipe to a brotli archive 96 92 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 97 93 guard_file_output(&output, "Brotli")?;
-4
src/backends/bzip2.rs
··· 82 82 "bzip2" 83 83 } 84 84 85 - fn clone_boxed(&self) -> Box<dyn Compressor> { 86 - Box::new(self.clone()) 87 - } 88 - 89 85 /// Compress an input file or pipe to a bz2 archive 90 86 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 91 87 guard_file_output(&output, "Bzip2")?;
-4
src/backends/gzip.rs
··· 56 56 "gzip" 57 57 } 58 58 59 - fn clone_boxed(&self) -> Box<dyn Compressor> { 60 - Box::new(self.clone()) 61 - } 62 - 63 59 /// Compress an input file or pipe to a gzip archive 64 60 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 65 61 guard_file_output(&output, "Gzip")?;
-4
src/backends/lz4.rs
··· 37 37 "lz4" 38 38 } 39 39 40 - fn clone_boxed(&self) -> Box<dyn Compressor> { 41 - Box::new(self.clone()) 42 - } 43 - 44 40 /// Compress an input file or pipe to a lz4 archive 45 41 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 46 42 guard_file_output(&output, "LZ4")?;
-4
src/backends/lzma.rs
··· 92 92 "lzma" 93 93 } 94 94 95 - fn clone_boxed(&self) -> Box<dyn Compressor> { 96 - Box::new(self.clone()) 97 - } 98 - 99 95 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 100 96 guard_file_output(&output, "LZMA")?; 101 97 let (input_stream, file_size) = open_input(input, "LZMA")?;
+8 -6
src/backends/pipeline.rs
··· 13 13 compressors: Vec<Box<dyn Compressor>>, 14 14 } 15 15 16 + impl Clone for Pipeline { 17 + fn clone(&self) -> Self { 18 + Pipeline { 19 + compressors: self.compressors.iter().map(|c| c.clone_boxed()).collect(), 20 + } 21 + } 22 + } 23 + 16 24 /// Which method intermediate (threaded) stages should invoke. The final stage 17 25 /// always runs on the calling thread and is handled by a caller-supplied 18 26 /// closure — only the intermediate layers need this dispatch. ··· 193 201 .last() 194 202 .expect("pipeline is never empty") 195 203 .name() 196 - } 197 - 198 - fn clone_boxed(&self) -> Box<dyn Compressor> { 199 - Box::new(Pipeline { 200 - compressors: self.compressors.iter().map(|c| c.clone_boxed()).collect(), 201 - }) 202 204 } 203 205 204 206 fn extension(&self) -> &str {
-4
src/backends/sevenz.rs
··· 111 111 "7z" 112 112 } 113 113 114 - fn clone_boxed(&self) -> Box<dyn Compressor> { 115 - Box::new(self.clone()) 116 - } 117 - 118 114 fn default_extracted_target(&self) -> ExtractedTarget { 119 115 ExtractedTarget::Directory 120 116 }
-4
src/backends/snappy.rs
··· 40 40 "snappy" 41 41 } 42 42 43 - fn clone_boxed(&self) -> Box<dyn Compressor> { 44 - Box::new(self.clone()) 45 - } 46 - 47 43 /// Compress an input file or pipe to a snappy frame-format archive 48 44 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 49 45 guard_file_output(&output, "Snappy")?;
-4
src/backends/tar.rs
··· 41 41 "tar" 42 42 } 43 43 44 - fn clone_boxed(&self) -> Box<dyn Compressor> { 45 - Box::new(self.clone()) 46 - } 47 - 48 44 /// Tar extracts to a directory by default 49 45 fn default_extracted_target(&self) -> ExtractedTarget { 50 46 ExtractedTarget::Directory
-4
src/backends/xz.rs
··· 58 58 "xz" 59 59 } 60 60 61 - fn clone_boxed(&self) -> Box<dyn Compressor> { 62 - Box::new(self.clone()) 63 - } 64 - 65 61 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 66 62 guard_file_output(&output, "Xz")?; 67 63 let (input_stream, file_size) = open_input(input, "Xz")?;
-4
src/backends/zip.rs
··· 120 120 "zip" 121 121 } 122 122 123 - fn clone_boxed(&self) -> Box<dyn Compressor> { 124 - Box::new(self.clone()) 125 - } 126 - 127 123 /// Zip extracts to a directory by default 128 124 fn default_extracted_target(&self) -> ExtractedTarget { 129 125 ExtractedTarget::Directory
-4
src/backends/zstd.rs
··· 79 79 "zstd" 80 80 } 81 81 82 - fn clone_boxed(&self) -> Box<dyn Compressor> { 83 - Box::new(self.clone()) 84 - } 85 - 86 82 /// Compress an input file or pipe to a zstd archive 87 83 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 88 84 guard_file_output(&output, "Zstd")?;
+19 -15
src/utils.rs
··· 172 172 } 173 173 } 174 174 175 + /// Produce an owned copy of a `Compressor` behind `Box<dyn Compressor>`, 176 + /// preserving all configuration (compression level, progress args, pipeline 177 + /// chain, etc). `Pipeline` uses this to hand owned instances to worker threads 178 + /// without losing user-supplied settings. 179 + /// 180 + /// Implementors don't write this manually — the blanket impl below covers any 181 + /// `Compressor + Clone + 'static`. `Clone` itself can't be a supertrait of 182 + /// `Compressor` because it would break object safety for `Box<dyn Compressor>`. 183 + pub trait CompressorClone { 184 + fn clone_boxed(&self) -> Box<dyn Compressor>; 185 + } 186 + 187 + impl<T: Compressor + Clone + 'static> CompressorClone for T { 188 + fn clone_boxed(&self) -> Box<dyn Compressor> { 189 + Box::new(self.clone()) 190 + } 191 + } 192 + 175 193 /// Common interface for all compressor implementations 176 - pub trait Compressor: Send + Sync { 194 + pub trait Compressor: CompressorClone + Send + Sync { 177 195 /// Name of this Compressor 178 196 fn name(&self) -> &str; 179 - 180 - /// Produce an owned copy of this compressor, preserving all configuration 181 - /// (compression level, progress args, pipeline chain, etc). `Pipeline` 182 - /// uses this to hand owned instances to worker threads without losing 183 - /// user-supplied settings. 184 - fn clone_boxed(&self) -> Box<dyn Compressor>; 185 197 186 198 /// Default extension for this Compressor 187 199 fn extension(&self) -> &str { ··· 326 338 "test" 327 339 } 328 340 329 - fn clone_boxed(&self) -> Box<dyn Compressor> { 330 - Box::new(self.clone()) 331 - } 332 - 333 341 // We'll use the default implementation for extension() and other methods 334 342 335 343 fn compress(&self, _: CmprssInput, _: CmprssOutput) -> Result { ··· 352 360 353 361 fn extension(&self) -> &str { 354 362 "cst" 355 - } 356 - 357 - fn clone_boxed(&self) -> Box<dyn Compressor> { 358 - Box::new(self.clone()) 359 363 } 360 364 361 365 fn compress(&self, _: CmprssInput, _: CmprssOutput) -> Result {