async_sevenz/
lib.rs

1//! This project is an async 7z compressor/decompressor written in pure Rust.
2//!
3//! This is a fork of [sevenz-rust2](https://github.com/hasenbanck/sevenz-rust2), then translated the api to async with [async-compression](https://crates.io/crates/async-compression) by AI.
4//!
5//! ## Supported Codecs & filters
6//!
7//! | Codec          | Decompression | Compression |
8//! |----------------|---------------|-------------|
9//! | COPY           | ✓             | ✓           |
10//! | LZMA           | ✓             | ✓           |
11//! | LZMA2          | ✓             | ✓           |
12//! | BROTLI (*)     | ✓             | ✓           |
13//! | BZIP2          | ✓             | ✓           |
14//! | DEFLATE (*)    | ✓             | ✓           |
15//! | PPMD           | ✓             | ✓           |
16//! | LZ4 (*)        | ✓             | ✓           |
17//! | ZSTD (*)       | ✓             | ✓           |
18//!
19//! (*) Require optional cargo feature.
20//!
21//! | Filter        | Decompression | Compression |
22//! |---------------|---------------|-------------|
23//! | BCJ X86       | ✓             | ✓           |
24//! | BCJ ARM       | ✓             | ✓           |
25//! | BCJ ARM64     | ✓             | ✓           |
26//! | BCJ ARM_THUMB | ✓             | ✓           |
27//! | BCJ RISC_V    | ✓             | ✓           |
28//! | BCJ PPC       | ✓             | ✓           |
29//! | BCJ SPARC     | ✓             | ✓           |
30//! | BCJ IA64      | ✓             | ✓           |
31//! | BCJ2          | ✓             |             |
32//! | DELTA         | ✓             | ✓           |
33//!
34//! # Usage
35//!
36//! ```rust
37//! use std::path::PathBuf;
38//!
39//! use tempfile::tempdir;
40//!
41//! use async_sevenz::decompress_file;
42//!
43//! let mut src = PathBuf::new();
44//! src.push("examples/data/sample.7z");
45//! let dest = tempdir().unwrap();
46//! smol::block_on(decompress_file(src, dest.path())).expect("complete");
47//! ```
48//!
49//! ## Decompress an encrypted 7z file
50//!
51//! ```rust
52//! # #[cfg(feature = "aes256")]
53//! # {
54//! use std::path::PathBuf;
55//!
56//! use tempfile::tempdir;
57//!
58//! use async_sevenz::decompress_file_with_password;
59//!
60//! let mut src = PathBuf::new();
61//! src.push("tests/resources/encrypted.7z");
62//! let dest = tempdir().unwrap();
63//! smol::block_on(decompress_file_with_password(src, dest.path(), "sevenz-rust".into()))
64//!     .expect("complete");
65//! # }
66//! ```
67//!
68//! # Compression
69//!
70//! ```rust
71//! # #[cfg(feature = "compress")]
72//! # {
73//! use std::path::PathBuf;
74//!
75//! use tempfile::tempdir;
76//!
77//! use async_sevenz::compress_to_path;
78//!
79//! let src = PathBuf::from("examples/data/sample");
80//! let dest_dir = tempdir().unwrap();
81//! let dest = dest_dir.path().join("sample.7z");
82//! smol::block_on(compress_to_path(src, &dest)).expect("compress ok");
83//! # }
84//! ```
85//!
86//! ## Compress with AES encryption
87//!
88//! ```rust
89//! # #[cfg(all(feature = "compress", feature = "aes256"))]
90//! # {
91//! use std::path::PathBuf;
92//!
93//! use tempfile::tempdir;
94//!
95//! use async_sevenz::compress_to_path_encrypted;
96//!
97//! let src = PathBuf::from("examples/data/sample");
98//! let dest_dir = tempdir().unwrap();
99//! let dest = dest_dir.path().join("sample_encrypted.7z");
100//! smol::block_on(compress_to_path_encrypted(src, &dest, "sevenz-rust".into()))
101//!     .expect("compress ok");
102//! # }
103//! ```
104//!
105//! ## Solid compression
106//!
107//! ```rust
108//! # #[cfg(feature = "compress")]
109//! # {
110//! use async_sevenz::ArchiveWriter;
111//!
112//! smol::block_on(async {
113//!     let mut writer = ArchiveWriter::create_in_memory()
114//!         .await
115//!         .expect("create writer ok");
116//!     writer
117//!         .push_source_path("examples/data/sample", |_| async { true })
118//!         .await
119//!         .expect("pack ok");
120//!     writer.finish().await.expect("compress ok");
121//! });
122//! # }
123//! ```
124//!
125//! ## Configure the compression methods
126//!
127//! ```rust
128//! # #[cfg(feature = "compress")]
129//! # {
130//! use async_sevenz::{ArchiveWriter, encoder_options};
131//!
132//! smol::block_on(async {
133//!     let mut writer = ArchiveWriter::create_in_memory()
134//!         .await
135//!         .expect("create writer ok");
136//!     writer.set_content_methods(vec![
137//!         encoder_options::AesEncoderOptions::new("sevenz-rust".into()).into(),
138//!         encoder_options::Lzma2Options::from_level(9).into(),
139//!     ]);
140//!     writer
141//!         .push_source_path("examples/data/sample", |_| async { true })
142//!         .await
143//!         .expect("pack ok");
144//!     writer.finish().await.expect("compress ok");
145//! });
146//! # }
147//! ```
148#![cfg_attr(docsrs, feature(doc_cfg))]
149#![warn(missing_docs)]
150
151#[cfg(target_arch = "wasm32")]
152extern crate wasm_bindgen;
153
154#[cfg(feature = "compress")]
155mod encoder;
156/// Encoding options when compressing.
157#[cfg(feature = "compress")]
158pub mod encoder_options;
159mod encryption;
160mod error;
161mod reader;
162
163#[cfg(feature = "compress")]
164mod writer;
165
166pub(crate) mod archive;
167pub(crate) mod bitset;
168pub(crate) mod block;
169mod codec;
170pub(crate) mod decoder;
171
172mod time;
173mod util;
174
175use std::ops::{Deref, DerefMut};
176
177pub use archive::*;
178pub use block::*;
179pub use encryption::Password;
180pub use error::Error;
181pub use reader::{ArchiveReader, BlockDecoder};
182pub use time::NtTime;
183#[cfg(all(feature = "compress", not(target_arch = "wasm32")))]
184pub use util::compress::*;
185#[cfg(not(target_arch = "wasm32"))]
186pub use util::decompress::*;
187#[cfg(target_arch = "wasm32")]
188pub use util::wasm::*;
189#[cfg(feature = "compress")]
190pub use writer::*;
191
192/// A trait for writers that finishes the stream on drop.
193pub trait AutoFinish {
194    /// Finish writing the stream without error handling.
195    fn finish_ignore_error(self);
196}
197
198/// A wrapper around a writer that finishes the stream on drop.
199pub struct AutoFinisher<T: AutoFinish>(Option<T>);
200
201impl<T: AutoFinish> Drop for AutoFinisher<T> {
202    fn drop(&mut self) {
203        if let Some(writer) = self.0.take() {
204            writer.finish_ignore_error();
205        }
206    }
207}
208
209impl<T: AutoFinish> Deref for AutoFinisher<T> {
210    type Target = T;
211
212    fn deref(&self) -> &Self::Target {
213        self.0.as_ref().unwrap()
214    }
215}
216
217impl<T: AutoFinish> DerefMut for AutoFinisher<T> {
218    fn deref_mut(&mut self) -> &mut Self::Target {
219        self.0.as_mut().unwrap()
220    }
221}