this repo has no description
0
fork

Configure Feed

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

feat: allow compressing/extracting to a pipe

+59 -10
+1
Cargo.lock
··· 114 114 dependencies = [ 115 115 "clap", 116 116 "flate2", 117 + "is-terminal", 117 118 "tar", 118 119 ] 119 120
+1
Cargo.toml
··· 15 15 clap = { version = "4.2.1", features = ["derive"] } 16 16 flate2 = "1.0" 17 17 tar = "0.4.38" 18 + is-terminal = "0.4" 18 19
+38 -6
src/main.rs
··· 3 3 mod utils; 4 4 5 5 use clap::{Args, Parser, Subcommand}; 6 + use is_terminal::IsTerminal; 6 7 use std::io; 7 8 use std::path::Path; 8 9 use utils::*; ··· 112 113 // Remove if you've created a stub 113 114 let args = compressor.common_args(); 114 115 let input_path = Path::new(&args.input); 115 - let out = output_filename(input_path, &args.output, compressor.extension()); 116 - compressor.compress_path_to_path(input_path, out) 116 + 117 + match &args.output { 118 + Some(out) => { 119 + // Output file specified, use that 120 + println!("Compressing {} into {}", input_path.display(), out); 121 + compressor.compress_path_to_path(input_path, out)?; 122 + } 123 + None => { 124 + // No output filename. Send to stdout if stream or guess the filename 125 + if std::io::stdout().is_terminal() { 126 + let out = output_filename(input_path, &args.output, compressor.extension()); 127 + println!("Compressing {} into {}", input_path.display(), out); 128 + compressor.compress_path_to_path(input_path, out)?; 129 + } else { 130 + // Stdout is a pipe, attempt to compress to that 131 + compressor.compress_file(input_path, std::io::stdout())?; 132 + } 133 + } 134 + } 135 + Ok(()) 117 136 } 118 137 119 138 /// Implement compression/extraction with a generic Compressor. ··· 123 142 if args.compress { 124 143 compress_generic(compressor)?; 125 144 } else if args.extract { 126 - let output = match args.output.as_ref() { 127 - Some(out) => out, 128 - None => ".", 145 + match &args.output { 146 + Some(out) => { 147 + // Output file specified, extract there 148 + compressor.extract_path_to_path(input_path, out)?; 149 + } 150 + None => { 151 + // No output file specified 152 + if std::io::stdout().is_terminal() { 153 + compressor.extract_path_to_path( 154 + input_path, 155 + compressor.default_extracted_filename(input_path), 156 + )?; 157 + } else { 158 + // Stdout is a pipe, extract to the pipe 159 + compressor.extract_file(input_path, std::io::stdout())?; 160 + } 161 + } 129 162 }; 130 - compressor.extract_path_to_path(input_path, output)?; 131 163 } else { 132 164 // Neither is set. 133 165 // Compress by default, warn if if looks like an archive.
+5 -2
src/tar.rs
··· 21 21 &self.common_args 22 22 } 23 23 24 + /// Tar extraction needs to specify the directory, so use the current directory 25 + fn default_extracted_filename(&self, _in_path: &Path) -> String { 26 + ".".to_string() 27 + } 28 + 24 29 /// Compress an input file or directory into a tar archive. 25 30 fn compress_file<I: AsRef<Path>, O: Write>( 26 31 &self, ··· 28 33 output: O, 29 34 ) -> Result<(), io::Error> { 30 35 let in_file = in_file.as_ref(); 31 - println!("tar: Compressing {}", in_file.display()); 32 36 let mut archive = Builder::new(output); 33 37 if in_file.is_file() { 34 38 archive.append_file(in_file.file_name().unwrap(), &mut File::open(in_file)?)?; ··· 58 62 input: I, 59 63 out_path: O, 60 64 ) -> Result<(), io::Error> { 61 - println!("tar extracting to {}", out_path.as_ref().display()); 62 65 let mut archive = Archive::new(input); 63 66 archive.unpack(out_path.as_ref()) 64 67 }
+14 -2
src/utils.rs
··· 20 20 self.name() 21 21 } 22 22 23 + /// Generate the default name for the compressed file 24 + fn default_compressed_filename(&self, in_path: &Path) -> String { 25 + format!( 26 + "{}.{}", 27 + in_path.file_name().unwrap().to_str().unwrap(), 28 + self.extension() 29 + ) 30 + } 31 + 32 + // Generate the default extracted filename 33 + fn default_extracted_filename(&self, in_path: &Path) -> String { 34 + in_path.file_stem().unwrap().to_str().unwrap().to_string() 35 + } 36 + 23 37 /// Getter method for the common arguments 24 38 // TODO: There is probably a cleaner way to do this? 25 39 fn common_args(&self) -> &CmprssCommonArgs; ··· 30 44 in_file: I, 31 45 out_file: O, 32 46 ) -> Result<(), io::Error> { 33 - println!("compress_path_to_path"); 34 47 self.compress_file(in_file, File::create(out_file)?) 35 48 } 36 49 ··· 40 53 in_file: I, 41 54 output: O, 42 55 ) -> Result<(), io::Error> { 43 - println!("compress_file"); 44 56 self.compress(File::open(in_file)?, output) 45 57 } 46 58