this repo has no description
0
fork

Configure Feed

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

feat(bzip2): add progress bar to bzip2

+67 -8
+67 -8
src/bzip2.rs
··· 1 - use crate::utils::*; 1 + use crate::{ 2 + progress::{progress_bar, ProgressArgs}, 3 + utils::*, 4 + }; 2 5 use bzip2::write::{BzDecoder, BzEncoder}; 3 6 use bzip2::Compression; 4 7 use clap::Args; ··· 13 16 pub common_args: CommonArgs, 14 17 15 18 #[clap(flatten)] 19 + pub progress_args: ProgressArgs, 20 + 21 + #[clap(flatten)] 16 22 pub level_args: LevelArgs, 17 23 } 18 24 19 25 pub struct Bzip2 { 20 26 pub level: u32, // 0-9 27 + pub progress_args: ProgressArgs, 21 28 } 22 29 23 30 impl Default for Bzip2 { 24 31 fn default() -> Self { 25 - Bzip2 { level: 6 } 32 + Bzip2 { 33 + level: 6, 34 + progress_args: ProgressArgs::default(), 35 + } 26 36 } 27 37 } 28 38 ··· 30 40 pub fn new(args: &Bzip2Args) -> Self { 31 41 Bzip2 { 32 42 level: args.level_args.level.level, 43 + progress_args: args.progress_args, 33 44 } 34 45 } 35 46 } ··· 47 58 48 59 /// Compress an input file or pipe to a bz2 archive 49 60 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 61 + let mut file_size = None; 50 62 let mut input_stream = match input { 51 63 CmprssInput::Path(paths) => { 52 64 if paths.len() > 1 { 53 65 return cmprss_error("only 1 file can be compressed at a time"); 54 66 } 55 - Box::new(File::open(paths[0].as_path())?) 67 + let file = Box::new(File::open(paths[0].as_path())?); 68 + // Get the file size for the progress bar 69 + if let Ok(metadata) = file.metadata() { 70 + file_size = Some(metadata.len()); 71 + } 72 + file 56 73 } 57 74 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 58 75 }; 59 - let output_stream: Box<dyn Write + Send> = match output { 76 + let output_stream: Box<dyn Write + Send> = match &output { 60 77 CmprssOutput::Path(path) => Box::new(File::create(path)?), 61 78 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 62 79 }; 63 80 let mut encoder = BzEncoder::new(output_stream, Compression::new(self.level)); 64 - io::copy(&mut input_stream, &mut encoder)?; 81 + let mut bar = progress_bar(file_size, self.progress_args.progress, &output); 82 + if let Some(progress) = &mut bar { 83 + // Copy the input to the output in chunks so that we can update the progress bar 84 + let mut buffer = vec![0; self.progress_args.chunk_size.size_in_bytes]; 85 + loop { 86 + let bytes_read = input_stream.read(&mut buffer)?; 87 + if bytes_read == 0 { 88 + break; 89 + } 90 + encoder.write_all(&buffer[..bytes_read])?; 91 + progress.update_input(encoder.total_in()); 92 + progress.update_output(encoder.total_out()); 93 + } 94 + encoder.flush()?; 95 + progress.update_output(encoder.total_out()); 96 + progress.finish(); 97 + } else { 98 + io::copy(&mut input_stream, &mut encoder)?; 99 + } 65 100 Ok(()) 66 101 } 67 102 68 103 /// Extract a bz2 archive to a file or pipe 69 104 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 105 + let mut file_size = None; 70 106 let mut input_stream = match input { 71 107 CmprssInput::Path(paths) => { 72 108 if paths.len() > 1 { 73 109 return cmprss_error("only 1 file can be extracted at a time"); 74 110 } 75 - Box::new(File::open(paths[0].as_path())?) 111 + let file = Box::new(File::open(paths[0].as_path())?); 112 + // Get the file size for the progress bar 113 + if let Ok(metadata) = file.metadata() { 114 + file_size = Some(metadata.len()); 115 + } 116 + file 76 117 } 77 118 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 78 119 }; 79 - let output_stream: Box<dyn Write + Send> = match output { 120 + let output_stream: Box<dyn Write + Send> = match &output { 80 121 CmprssOutput::Path(path) => Box::new(File::create(path)?), 81 122 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 82 123 }; 83 124 let mut decoder = BzDecoder::new(output_stream); 84 - io::copy(&mut input_stream, &mut decoder)?; 125 + let mut bar = progress_bar(file_size, self.progress_args.progress, &output); 126 + if let Some(progress) = &mut bar { 127 + // Copy the input to the output in chunks so that we can update the progress bar 128 + let mut buffer = vec![0; self.progress_args.chunk_size.size_in_bytes]; 129 + loop { 130 + let bytes_read = input_stream.read(&mut buffer)?; 131 + if bytes_read == 0 { 132 + break; 133 + } 134 + decoder.write_all(&buffer[..bytes_read])?; 135 + progress.update_input(decoder.total_in()); 136 + progress.update_output(decoder.total_out()); 137 + } 138 + decoder.flush()?; 139 + progress.update_output(decoder.total_out()); 140 + progress.finish(); 141 + } else { 142 + io::copy(&mut input_stream, &mut decoder)?; 143 + } 85 144 Ok(()) 86 145 } 87 146 }