this repo has no description
0
fork

Configure Feed

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

at f7bbb7638e8ed85d5c92d23cfdcf38ed665b3b21 143 lines 3.7 kB view raw
1use super::stream::{guard_file_output, open_input, open_output}; 2use crate::{ 3 progress::{ProgressArgs, copy_with_progress}, 4 utils::*, 5}; 6use clap::Args; 7use std::io; 8use xz2::read::XzDecoder; 9use xz2::write::XzEncoder; 10 11#[derive(Args, Debug)] 12pub struct XzArgs { 13 #[clap(flatten)] 14 pub common_args: CommonArgs, 15 16 #[clap(flatten)] 17 progress_args: ProgressArgs, 18 19 #[clap(flatten)] 20 pub level_args: LevelArgs, 21} 22 23pub struct Xz { 24 pub level: i32, 25 pub progress_args: ProgressArgs, 26} 27 28impl Default for Xz { 29 fn default() -> Self { 30 let validator = DefaultCompressionValidator; 31 Xz { 32 level: validator.default_level(), 33 progress_args: ProgressArgs::default(), 34 } 35 } 36} 37 38impl Xz { 39 pub fn new(args: &XzArgs) -> Xz { 40 Xz { 41 level: args.level_args.resolve(&DefaultCompressionValidator), 42 progress_args: args.progress_args, 43 } 44 } 45} 46 47impl Compressor for Xz { 48 /// The standard extension for the xz format. 49 fn extension(&self) -> &str { 50 "xz" 51 } 52 53 /// Full name for xz. 54 fn name(&self) -> &str { 55 "xz" 56 } 57 58 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result { 59 guard_file_output(&output, "Xz")?; 60 let (mut input_stream, file_size) = open_input(input, "Xz")?; 61 62 if let CmprssOutput::Writer(writer) = output { 63 let mut encoder = XzEncoder::new(writer, self.level as u32); 64 io::copy(&mut input_stream, &mut encoder)?; 65 encoder.finish()?; 66 } else { 67 let output_stream = open_output(&output)?; 68 let mut encoder = XzEncoder::new(output_stream, self.level as u32); 69 copy_with_progress( 70 &mut input_stream, 71 &mut encoder, 72 self.progress_args.chunk_size.size_in_bytes, 73 file_size, 74 self.progress_args.progress, 75 &output, 76 )?; 77 } 78 79 Ok(()) 80 } 81 82 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result { 83 guard_file_output(&output, "Xz")?; 84 let (input_stream, file_size) = open_input(input, "Xz")?; 85 let mut decoder = XzDecoder::new(input_stream); 86 87 if let CmprssOutput::Writer(mut writer) = output { 88 io::copy(&mut decoder, &mut writer)?; 89 } else { 90 let mut output_stream = open_output(&output)?; 91 copy_with_progress( 92 &mut decoder, 93 &mut output_stream, 94 self.progress_args.chunk_size.size_in_bytes, 95 file_size, 96 self.progress_args.progress, 97 &output, 98 )?; 99 } 100 101 Ok(()) 102 } 103} 104 105#[cfg(test)] 106mod tests { 107 use super::*; 108 use crate::test_utils::*; 109 110 /// Test the basic interface of the Xz compressor 111 #[test] 112 fn test_xz_interface() { 113 let compressor = Xz::default(); 114 test_compressor_interface(&compressor, "xz", Some("xz")); 115 } 116 117 /// Test the default compression level 118 #[test] 119 fn test_xz_default_compression() -> Result { 120 let compressor = Xz::default(); 121 test_compression(&compressor) 122 } 123 124 /// Test fast compression level 125 #[test] 126 fn test_xz_fast_compression() -> Result { 127 let fast_compressor = Xz { 128 level: 1, 129 progress_args: ProgressArgs::default(), 130 }; 131 test_compression(&fast_compressor) 132 } 133 134 /// Test best compression level 135 #[test] 136 fn test_xz_best_compression() -> Result { 137 let best_compressor = Xz { 138 level: 9, 139 progress_args: ProgressArgs::default(), 140 }; 141 test_compression(&best_compressor) 142 } 143}