diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ed9d4b7..219e51f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: - name: Install Rust specified toolchain run: rustup show - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.4 - name: Install just, nextest, cargo-llvm-cov, and cargo-hack uses: taiki-e/install-action@v2 with: @@ -58,7 +58,7 @@ jobs: - name: Install Rust specified toolchain run: rustup show - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.4 - name: Install cargo-nextest uses: taiki-e/install-action@v2 with: @@ -81,7 +81,7 @@ jobs: - name: Install Rust specified toolchain run: rustup show - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.4 - name: Install cargo-nextest uses: taiki-e/install-action@v2 with: diff --git a/.vscode/settings.json b/.vscode/settings.json index 9a92fea..a647584 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "rust-analyzer.cargo.features": ["default", "lzma", "deflate64"] + "rust-analyzer.cargo.features": ["default", "lzma", "deflate64", "bzip2"] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 4ddb170..e843b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,6 +98,27 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "cc" version = "1.0.83" @@ -562,6 +583,12 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + [[package]] name = "portable-atomic" version = "1.6.0" @@ -632,6 +659,7 @@ name = "rc-zip" version = "2.0.1" dependencies = [ "byteorder", + "bzip2", "cfg-if", "chardetng", "chrono", diff --git a/crates/rc-zip/Cargo.toml b/crates/rc-zip/Cargo.toml index 7b68b67..c7ac2c9 100644 --- a/crates/rc-zip/Cargo.toml +++ b/crates/rc-zip/Cargo.toml @@ -29,6 +29,7 @@ byteorder = "1.5.0" cfg-if = "1.0.0" lzma-rs = { version = "0.3.0", features = ["stream"], optional = true } deflate64 = { version = "0.1.7", optional = true } +bzip2 = { version = "0.4.4", optional = true } [features] default = ["sync", "file", "deflate"] @@ -37,6 +38,7 @@ file = ["positioned-io"] deflate = ["dep:flate2"] deflate64 = ["dep:deflate64"] lzma = ["dep:lzma-rs"] +bzip2 = ["dep:bzip2"] [dev-dependencies] tracing-test = "0.2.4" diff --git a/crates/rc-zip/src/reader/sync/entry_reader/bzip2_dec.rs b/crates/rc-zip/src/reader/sync/entry_reader/bzip2_dec.rs new file mode 100644 index 0000000..c8c0bc8 --- /dev/null +++ b/crates/rc-zip/src/reader/sync/entry_reader/bzip2_dec.rs @@ -0,0 +1,22 @@ +use std::io::Read; + +use bzip2::read::BzDecoder; + +use crate::reader::sync::{Decoder, LimitedReader}; + +impl Decoder for BzDecoder +where + R: Read, +{ + fn into_inner(self: Box) -> R { + Self::into_inner(*self) + } + + fn get_mut(&mut self) -> &mut R { + Self::get_mut(self) + } +} + +pub(crate) fn mk_decoder(r: LimitedReader) -> impl Decoder { + BzDecoder::new(r) +} diff --git a/crates/rc-zip/src/reader/sync/entry_reader/mod.rs b/crates/rc-zip/src/reader/sync/entry_reader/mod.rs index 39b88ef..9be6e2a 100644 --- a/crates/rc-zip/src/reader/sync/entry_reader/mod.rs +++ b/crates/rc-zip/src/reader/sync/entry_reader/mod.rs @@ -16,6 +16,9 @@ mod deflate_dec; #[cfg(feature = "deflate64")] mod deflate64_dec; +#[cfg(feature = "bzip2")] +mod bzip2_dec; + use cfg_if::cfg_if; use nom::Offset; use oval::Buffer; @@ -297,6 +300,15 @@ where } } } + Method::Bzip2 => { + cfg_if! { + if #[cfg(feature = "bzip2")] { + Box::new(bzip2_dec::mk_decoder(limited_reader)) + } else { + return Err(Error::method_not_enabled(self.method)); + } + } + } method => { return Err(Error::method_not_supported(method)); } diff --git a/crates/rc-zip/src/tests.rs b/crates/rc-zip/src/tests.rs index 51c5eb1..50331b4 100644 --- a/crates/rc-zip/src/tests.rs +++ b/crates/rc-zip/src/tests.rs @@ -296,6 +296,19 @@ fn test_cases() -> Vec { }], ..Default::default() }, + // same with bzip2 + #[cfg(feature = "bzip2")] + ZipTest { + source: ZipSource::File("found-me-bzip2.zip"), + expected_encoding: Some(Encoding::Utf8), + files: vec![ZipTestFile { + name: "found-me.txt", + content: FileContent::Bytes("Oh no, you found me\n".repeat(5000).into()), + modified: Some(date((2024, 1, 26), (17, 14, 36), 0, time_zone(0)).unwrap()), + ..Default::default() + }], + ..Default::default() + }, ] }