diff --git a/CHANGELOG.md b/CHANGELOG.md index 9df68ee0..d831fdb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Support bzip2 compression type (`CompressionType::Bzip2`). + ### Changed - `Error` now implements `Send + Sync` (therefore, `Result` now implements `Send + Sync`). diff --git a/Cargo.toml b/Cargo.toml index 429754e8..1172a48e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ itertools = "0.12" hex = { version = "0.4", features = ["std"] } zstd = "0.13" xz2 = "0.1" +bzip2 = "0.4.4" [dev-dependencies] env_logger = "0.10.0" diff --git a/src/errors.rs b/src/errors.rs index fe234316..da68ce1a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -89,7 +89,7 @@ pub enum Error { #[error("unable to find key with key-ref: {key_ref}")] KeyNotFoundError { key_ref: String }, - #[error("unknown compressor type {0} - only gzip and none are supported")] + #[error("unknown compressor type {0} - supported types: gzip, zstd, xz, bzip2 and none")] UnknownCompressorType(String), #[error("unsupported digest algorithm {0:?}")] diff --git a/src/rpm/builder.rs b/src/rpm/builder.rs index 0c5f3631..37e5db0d 100644 --- a/src/rpm/builder.rs +++ b/src/rpm/builder.rs @@ -1052,6 +1052,7 @@ impl PackageBuilder { CompressionWithLevel::Gzip(level) => Some(("gzip".to_owned(), level.to_string())), CompressionWithLevel::Zstd(level) => Some(("zstd".to_owned(), level.to_string())), CompressionWithLevel::Xz(level) => Some(("xz".to_owned(), level.to_string())), + CompressionWithLevel::Bzip2(level) => Some(("bzip2".to_owned(), level.to_string())), }; if let Some((compression_name, compression_level)) = compression_details { diff --git a/src/rpm/compressor.rs b/src/rpm/compressor.rs index 8390b737..b00221f5 100644 --- a/src/rpm/compressor.rs +++ b/src/rpm/compressor.rs @@ -10,6 +10,7 @@ pub enum CompressionType { Gzip, Zstd, Xz, + Bzip2, } impl std::str::FromStr for CompressionType { @@ -19,6 +20,7 @@ impl std::str::FromStr for CompressionType { "gzip" => Ok(CompressionType::Gzip), "zstd" => Ok(CompressionType::Zstd), "xz" => Ok(CompressionType::Xz), + "bzip2" => Ok(CompressionType::Bzip2), _ => Err(Error::UnknownCompressorType(raw.to_string())), } } @@ -29,6 +31,7 @@ pub enum Compressor { Gzip(flate2::write::GzEncoder>), Zstd(zstd::stream::Encoder<'static, Vec>), Xz(xz2::write::XzEncoder>), + Bzip2(bzip2::write::BzEncoder>), } impl TryFrom for Compressor { @@ -48,6 +51,9 @@ impl TryFrom for Compressor { Vec::new(), level, ))), + CompressionWithLevel::Bzip2(level) => Ok(Compressor::Bzip2( + bzip2::write::BzEncoder::new(Vec::new(), bzip2::Compression::new(level)), + )), } } } @@ -59,6 +65,7 @@ impl Write for Compressor { Compressor::Gzip(encoder) => encoder.write(content), Compressor::Zstd(encoder) => encoder.write(content), Compressor::Xz(encoder) => encoder.write(content), + Compressor::Bzip2(encoder) => encoder.write(content), } } fn flush(&mut self) -> Result<(), std::io::Error> { @@ -67,6 +74,7 @@ impl Write for Compressor { Compressor::Gzip(encoder) => encoder.flush(), Compressor::Zstd(encoder) => encoder.flush(), Compressor::Xz(encoder) => encoder.flush(), + Compressor::Bzip2(encoder) => encoder.flush(), } } } @@ -78,6 +86,7 @@ impl Compressor { Compressor::Gzip(encoder) => Ok(encoder.finish()?), Compressor::Zstd(encoder) => Ok(encoder.finish()?), Compressor::Xz(encoder) => Ok(encoder.finish()?), + Compressor::Bzip2(encoder) => Ok(encoder.finish()?), } } } @@ -90,6 +99,7 @@ pub enum CompressionWithLevel { Zstd(i32), Gzip(u32), Xz(u32), + Bzip2(u32), } impl CompressionWithLevel { @@ -99,6 +109,7 @@ impl CompressionWithLevel { Self::Gzip(_) => CompressionType::Gzip, Self::Zstd(_) => CompressionType::Zstd, Self::Xz(_) => CompressionType::Xz, + Self::Bzip2(_) => CompressionType::Bzip2, } } } @@ -116,6 +127,7 @@ impl From for CompressionWithLevel { CompressionType::Gzip => CompressionWithLevel::Gzip(9), CompressionType::Xz => CompressionWithLevel::Xz(9), CompressionType::Zstd => CompressionWithLevel::Zstd(19), + CompressionType::Bzip2 => CompressionWithLevel::Bzip2(9), } } } diff --git a/tests/parsing.rs b/tests/parsing.rs index fa2b2526..f871ae3a 100644 --- a/tests/parsing.rs +++ b/tests/parsing.rs @@ -64,6 +64,7 @@ fn test_package_segment_boundaries() -> Result<(), Box> { CompressionType::Gzip => &[0x1f, 0x8b], CompressionType::Zstd => &[0x28, 0xb5, 0x2f, 0xfd], CompressionType::Xz => &[0xfd, 0x37, 0x7a, 0x58, 0x5a], + CompressionType::Bzip2 => &[0x42, 0x5a], CompressionType::None => &[0x30, 0x37, 0x30, 0x37, 0x30, 0x31], // CPIO archive magic # };