diff --git a/src/commands.rs b/src/commands.rs index ab5100830..de2722d0f 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -246,10 +246,24 @@ fn compress_files( writer.flush()?; } Tgz => { - // Wrap it into an gz_decoder, and pass to the tar archive builder - let gz_decoder = flate2::write::GzEncoder::new(writer, Default::default()); - let mut writer = archive::tar::build_archive_from_paths(&files, gz_decoder)?; - writer.flush()?; + let encoder = flate2::write::GzEncoder::new(writer, Default::default()); + let writer = archive::tar::build_archive_from_paths(&files, encoder)?; + writer.finish()?.flush()?; + } + Tbz => { + let encoder = bzip2::write::BzEncoder::new(writer, Default::default()); + let writer = archive::tar::build_archive_from_paths(&files, encoder)?; + writer.finish()?.flush()?; + } + Tlzma => { + let encoder = xz2::write::XzEncoder::new(writer, 6); + let writer = archive::tar::build_archive_from_paths(&files, encoder)?; + writer.finish()?.flush()?; + } + Tzst => { + let encoder = zstd::stream::write::Encoder::new(writer, Default::default())?; + let writer = archive::tar::build_archive_from_paths(&files, encoder)?; + writer.finish()?.flush()?; } Zip => { eprintln!("{yellow}Warning:{reset}", yellow = *colors::YELLOW, reset = *colors::RESET); @@ -349,6 +363,21 @@ fn decompress_file( let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?; info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); } + Tbz => { + let reader = chain_reader_decoder(&Bzip, reader)?; + let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?; + info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + } + Tlzma => { + let reader = chain_reader_decoder(&Lzma, reader)?; + let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?; + info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + } + Tzst => { + let reader = chain_reader_decoder(&Zstd, reader)?; + let _ = crate::archive::tar::unpack_archive(reader, output_folder, flags)?; + info!("Successfully uncompressed archive in '{}'.", to_utf(output_folder)); + } Zip => { eprintln!("Compressing first into .zip."); eprintln!("Warning: .zip archives with extra extensions have a downside."); diff --git a/src/extension.rs b/src/extension.rs index aa2777a99..b1828f063 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -7,13 +7,16 @@ use self::CompressionFormat::*; #[derive(Clone, PartialEq, Eq, Debug)] /// Accepted extensions for input and output pub enum CompressionFormat { - Gzip, // .gz - Bzip, // .bz - Lzma, // .lzma - Tar, // .tar (technically not a compression extension, but will do for now) - Tgz, // .tgz - Zstd, // .zst - Zip, // .zip + Gzip, // .gz + Bzip, // .bz + Lzma, // .lzma + Tar, // .tar (technically not a compression extension, but will do for now) + Tgz, // .tgz + Tbz, // .tbz + Tlzma, // .tlzma + Tzst, // .tzst + Zstd, // .zst + Zip, // .zip } impl fmt::Display for CompressionFormat { @@ -28,6 +31,9 @@ impl fmt::Display for CompressionFormat { Lzma => ".lz", Tar => ".tar", Tgz => ".tgz", + Tbz => ".tbz", + Tlzma => ".tlz", + Tzst => ".tzst", Zip => ".zip", } ) @@ -50,6 +56,9 @@ pub fn separate_known_extensions_from_name(mut path: &Path) -> (&Path, Vec Tar, "tgz" => Tgz, + "tbz" | "tbz2" => Tbz, + "txz" | "tlz" | "tlzma" => Tlzma, + "tzst" => Tzst, "zip" => Zip, "bz" | "bz2" => Bzip, "gz" => Gzip, diff --git a/tests/compress_and_decompress.rs b/tests/compress_and_decompress.rs index e97ab339e..08e536775 100644 --- a/tests/compress_and_decompress.rs +++ b/tests/compress_and_decompress.rs @@ -27,7 +27,10 @@ fn sanity_check_through_mime() { let bytes = generate_random_file_content(&mut SmallRng::from_entropy()); test_file.write_all(&bytes).expect("to successfully write bytes to the file"); - let formats = ["tar", "zip", "tar.gz", "tgz", "tar.bz", "tar.bz2", "tar.lzma", "tar.xz", "tar.zst"]; + let formats = [ + "tar", "zip", "tar.gz", "tgz", "tbz", "tbz2", "txz", "tlz", "tlzma", "tzst", "tar.bz", "tar.bz2", "tar.lzma", + "tar.xz", "tar.zst", + ]; let expected_mimes = [ "application/x-tar", @@ -38,6 +41,12 @@ fn sanity_check_through_mime() { "application/x-bzip2", "application/x-xz", "application/x-xz", + "application/x-xz", + "application/zstd", + "application/x-bzip2", + "application/x-bzip2", + "application/x-xz", + "application/x-xz", "application/zstd", ]; @@ -69,6 +78,12 @@ fn test_each_format() { test_compressing_and_decompressing_archive("tar.lzma"); test_compressing_and_decompressing_archive("tar.zst"); test_compressing_and_decompressing_archive("tgz"); + test_compressing_and_decompressing_archive("tbz"); + test_compressing_and_decompressing_archive("tbz2"); + test_compressing_and_decompressing_archive("txz"); + test_compressing_and_decompressing_archive("tlz"); + test_compressing_and_decompressing_archive("tlzma"); + test_compressing_and_decompressing_archive("tzst"); test_compressing_and_decompressing_archive("zip"); test_compressing_and_decompressing_archive("zip.gz"); test_compressing_and_decompressing_archive("zip.bz");