this repo has no description
0
fork

Configure Feed

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

at tangled-ci 170 lines 4.6 kB view raw
1use super::stream::{copy_stream, guard_file_output, open_input, prepare_output}; 2use crate::progress::ProgressArgs; 3use crate::utils::{ 4 CmprssInput, CmprssOutput, CommonArgs, CompressionLevelValidator, Compressor, LevelArgs, Result, 5}; 6use clap::Args; 7use zstd::stream::{read::Decoder, write::Encoder}; 8 9/// Zstd-specific compression validator (-7 to 22 range) 10#[derive(Debug, Clone, Copy)] 11pub struct ZstdCompressionValidator; 12 13impl CompressionLevelValidator for ZstdCompressionValidator { 14 fn min_level(&self) -> i32 { 15 -7 16 } 17 fn max_level(&self) -> i32 { 18 22 19 } 20 fn default_level(&self) -> i32 { 21 1 22 } 23 24 fn name_to_level(&self, name: &str) -> Option<i32> { 25 match name.to_lowercase().as_str() { 26 "none" => Some(-7), 27 "fast" => Some(1), 28 "best" => Some(22), 29 _ => None, 30 } 31 } 32} 33 34#[derive(Args, Debug)] 35pub struct ZstdArgs { 36 #[clap(flatten)] 37 pub common_args: CommonArgs, 38 39 #[clap(flatten)] 40 pub level_args: LevelArgs, 41 42 #[clap(flatten)] 43 pub progress_args: ProgressArgs, 44} 45 46#[derive(Clone)] 47pub struct Zstd { 48 pub compression_level: i32, 49 pub progress_args: ProgressArgs, 50} 51 52impl Default for Zstd { 53 fn default() -> Self { 54 let validator = ZstdCompressionValidator; 55 Zstd { 56 compression_level: validator.default_level(), 57 progress_args: ProgressArgs::default(), 58 } 59 } 60} 61 62impl Zstd { 63 pub fn new(args: &ZstdArgs) -> Zstd { 64 Zstd { 65 compression_level: args.level_args.resolve(&ZstdCompressionValidator), 66 progress_args: args.progress_args, 67 } 68 } 69} 70 71impl Compressor for Zstd { 72 /// The standard extension for the zstd format. 73 fn extension(&self) -> &str { 74 "zst" 75 } 76 77 /// Full name for zstd. 78 fn name(&self) -> &str { 79 "zstd" 80 } 81 82 /// Compress an input file or pipe to a zstd archive 83 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 84 guard_file_output(&output, "Zstd")?; 85 let (input_stream, file_size, pipeline_inner) = open_input(input, "Zstd")?; 86 let (writer, target) = prepare_output(output)?; 87 let mut encoder = Encoder::new(writer, self.compression_level)?; 88 copy_stream( 89 input_stream, 90 &mut encoder, 91 file_size, 92 pipeline_inner, 93 &self.progress_args, 94 target, 95 )?; 96 encoder.finish()?; 97 Ok(()) 98 } 99 100 /// Extract a zstd archive to an output file or pipe 101 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result { 102 guard_file_output(&output, "Zstd")?; 103 let (input_stream, file_size, pipeline_inner) = open_input(input, "Zstd")?; 104 let decoder = Decoder::new(input_stream)?; 105 let (writer, target) = prepare_output(output)?; 106 copy_stream( 107 decoder, 108 writer, 109 file_size, 110 pipeline_inner, 111 &self.progress_args, 112 target, 113 )?; 114 Ok(()) 115 } 116} 117 118#[cfg(test)] 119mod tests { 120 use super::*; 121 use crate::test_utils::*; 122 123 /// Test the basic interface of the Zstd compressor 124 #[test] 125 fn test_zstd_interface() { 126 let compressor = Zstd::default(); 127 test_compressor_interface(&compressor, "zstd", Some("zst")); 128 } 129 130 /// Test the default compression level 131 #[test] 132 fn test_zstd_default_compression() -> Result { 133 let compressor = Zstd::default(); 134 test_compression(&compressor) 135 } 136 137 /// Test fast compression level 138 #[test] 139 fn test_zstd_fast_compression() -> Result { 140 let fast_compressor = Zstd { 141 compression_level: 1, 142 progress_args: ProgressArgs::default(), 143 }; 144 test_compression(&fast_compressor) 145 } 146 147 /// Test best compression level 148 #[test] 149 fn test_zstd_best_compression() -> Result { 150 let best_compressor = Zstd { 151 compression_level: 22, 152 progress_args: ProgressArgs::default(), 153 }; 154 test_compression(&best_compressor) 155 } 156 157 #[test] 158 fn test_zstd_compression_validator() { 159 let validator = ZstdCompressionValidator; 160 test_compression_validator_helper( 161 &validator, 162 -7, // min_level 163 22, // max_level 164 1, // default_level 165 Some(1), // fast_name_level 166 Some(22), // best_name_level 167 Some(-7), // none_name_level 168 ); 169 } 170}