···2727 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> {
2828 match (input, output) {
2929 (CmprssInput::Path(in_path), CmprssOutput::Path(out_path)) => {
3030- self.compress_internal(File::open(in_path)?, File::create(out_path)?)
3030+ let mut encoder = GzEncoder::new(
3131+ File::create(out_path)?,
3232+ Compression::new(self.compression_level),
3333+ );
3434+ for x in in_path {
3535+ std::io::copy(&mut File::open(x)?, &mut encoder)?;
3636+ }
3737+ encoder.finish()?;
3838+ Ok(())
3139 }
3240 (CmprssInput::Path(in_path), CmprssOutput::Pipe(out_pipe)) => {
3333- self.compress_internal(File::open(in_path)?, out_pipe)
4141+ let mut encoder =
4242+ GzEncoder::new(out_pipe, Compression::new(self.compression_level));
4343+ for x in in_path {
4444+ std::io::copy(&mut File::open(x)?, &mut encoder)?;
4545+ }
4646+ encoder.finish()?;
4747+ Ok(())
3448 }
3549 (CmprssInput::Pipe(in_pipe), CmprssOutput::Path(out_path)) => {
3650 self.compress_internal(in_pipe, File::create(out_path)?)
···4458 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> {
4559 match (input, output) {
4660 (CmprssInput::Path(in_path), CmprssOutput::Path(out_path)) => {
4747- self.extract_internal(File::open(in_path)?, File::create(out_path)?)
6161+ if in_path.len() > 1 {
6262+ return cmprss_error("only 1 archive can be extracted at a time");
6363+ }
6464+ self.extract_internal(File::open(in_path[0])?, File::create(out_path)?)
4865 }
4966 (CmprssInput::Path(in_path), CmprssOutput::Pipe(out_pipe)) => {
5050- self.extract_internal(File::open(in_path)?, out_pipe)
6767+ if in_path.len() > 1 {
6868+ return cmprss_error("only 1 archive can be extracted at a time");
6969+ }
7070+ self.extract_internal(File::open(in_path[0])?, out_pipe)
5171 }
5272 (CmprssInput::Pipe(in_pipe), CmprssOutput::Path(out_path)) => {
5373 self.extract_internal(in_pipe, File::create(out_path)?)
+7-5
src/main.rs
···132132 false => CmprssInput::Pipe(std::io::stdin()),
133133 true => {
134134 // stdin isn't a pipe, need to read from a file
135135- CmprssInput::Path(Path::new(get_input_filename(&args.input)?))
135135+ CmprssInput::Path(vec![Path::new(get_input_filename(&args.input)?)])
136136 }
137137 };
138138 // Output prefers the stdout if we're piping, and falls back to piping to a file.
···164164 // Neither compress nor extract is specified.
165165 // Compress by default, warn if if looks like an archive.
166166 match &input {
167167- CmprssInput::Path(path) => {
168168- if let Some(ext) = path.extension() {
169169- if ext == compressor.extension() {
170170- return cmprss_error(
167167+ CmprssInput::Path(paths) => {
168168+ for x in paths {
169169+ if let Some(ext) = x.extension() {
170170+ if ext == compressor.extension() {
171171+ return cmprss_error(
171172 &format!("error: input appears to already be a {} archive, exiting. Use '--compress' if needed.", compressor.name()));
173173+ }
172174 }
173175 }
174176 compressor.compress(input, output)?;
+18-13
src/tar.rs
···37373838 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> {
3939 match input {
4040- CmprssInput::Path(path) => {
4141- self.extract_internal(Archive::new(File::open(path)?), output)
4040+ CmprssInput::Path(paths) => {
4141+ if paths.len() > 1 {
4242+ return cmprss_error("only 1 archive can be extracted at a time");
4343+ }
4444+ self.extract_internal(Archive::new(File::open(paths[0])?), output)
4245 }
4346 CmprssInput::Pipe(pipe) => self.extract_internal(Archive::new(pipe), output),
4447 }
···6770 input: CmprssInput,
6871 mut archive: Builder<W>,
6972 ) -> Result<(), io::Error> {
7070- let in_file = match input {
7171- CmprssInput::Path(path) => path,
7373+ let input_files = match input {
7474+ CmprssInput::Path(paths) => paths,
7275 CmprssInput::Pipe(_) => {
7376 return cmprss_error("error: tar does not support stdin as input")
7477 }
7578 };
7676- if in_file.is_file() {
7777- archive.append_file(in_file.file_name().unwrap(), &mut File::open(in_file)?)?;
7878- } else if in_file.is_dir() {
7979- archive.append_dir_all(in_file.file_name().unwrap(), in_file)?;
8080- } else {
8181- return Err(io::Error::new(
8282- io::ErrorKind::InvalidInput,
8383- "unknown file type",
8484- ));
7979+ for in_file in input_files {
8080+ if in_file.is_file() {
8181+ archive.append_file(in_file.file_name().unwrap(), &mut File::open(in_file)?)?;
8282+ } else if in_file.is_dir() {
8383+ archive.append_dir_all(in_file.file_name().unwrap(), in_file)?;
8484+ } else {
8585+ return Err(io::Error::new(
8686+ io::ErrorKind::InvalidInput,
8787+ "unknown file type",
8888+ ));
8989+ }
8590 }
8691 archive.finish()
8792 }
+3-1
src/utils.rs
···5353/// Defines the possible inputs of a compressor
5454// TODO: Implement fmt for CmprssInput/CmprssOutput
5555pub enum CmprssInput<'a> {
5656- Path(&'a Path),
5656+ /// Path(s) to the input files.
5757+ Path(Vec<&'a Path>),
5858+ /// Input pipe
5759 Pipe(std::io::Stdin),
5860}
5961