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//! #[tokio::main]
44//! async fn main() {
45//!     let mut src = PathBuf::new();
46//!     src.push("examples/data/sample.7z");
47//!     let dest = tempdir().unwrap();
48//!     decompress_file(src, dest.path()).await.expect("complete");
49//! }
50//! ```
51//!
52//! ## Decompress an encrypted 7z file
53//!
54//! ```rust
55//! # #[cfg(feature = "aes256")]
56//! # {
57//! use std::path::PathBuf;
58//!
59//! use tempfile::tempdir;
60//!
61//! use async_sevenz::decompress_file_with_password;
62//!
63//! #[tokio::main]
64//! async fn main() {
65//!     let mut src = PathBuf::new();
66//!     src.push("tests/resources/encrypted.7z");
67//!     let dest = tempdir().unwrap();
68//!     decompress_file_with_password(src, dest.path(), "sevenz-rust".into()).await
69//!         .expect("complete");
70//! }
71//! # }
72//! ```
73//!
74//! # Compression
75//!
76//! ```rust
77//! # #[cfg(feature = "compress")]
78//! # {
79//! use std::path::PathBuf;
80//!
81//! use tempfile::tempdir;
82//!
83//! use async_sevenz::compress_to_path;
84//!
85//! #[tokio::main]
86//! async fn main() {
87//!     let src = PathBuf::from("examples/data/sample");
88//!     let dest_dir = tempdir().unwrap();
89//!     let dest = dest_dir.path().join("sample.7z");
90//!     compress_to_path(src, &dest).await.expect("compress ok");
91//! }
92//! # }
93//! ```
94//!
95//! ## Compress with AES encryption
96//!
97//! ```rust
98//! # #[cfg(all(feature = "compress", feature = "aes256"))]
99//! # {
100//! use std::path::PathBuf;
101//!
102//! use tempfile::tempdir;
103//!
104//! use async_sevenz::compress_to_path_encrypted;
105//!
106//! #[tokio::main]
107//! async fn main() {
108//!     let src = PathBuf::from("examples/data/sample");
109//!     let dest_dir = tempdir().unwrap();
110//!     let dest = dest_dir.path().join("sample_encrypted.7z");
111//!     compress_to_path_encrypted(src, &dest, "sevenz-rust".into()).await
112//!         .expect("compress ok");
113//! }
114//! # }
115//! ```
116//!
117//! ## Solid compression
118//!
119//! ```rust
120//! # #[cfg(feature = "compress")]
121//! # {
122//! use async_sevenz::ArchiveWriter;
123//!
124//! #[tokio::main]
125//! async fn main() {
126//!     let mut writer = ArchiveWriter::create_in_memory()
127//!         .await
128//!         .expect("create writer ok");
129//!     writer
130//!         .push_source_path("examples/data/sample", |_| async { true })
131//!         .await
132//!         .expect("pack ok");
133//!     writer.finish().await.expect("compress ok");
134//! }
135//! # }
136//! ```
137//!
138//! ## Configure the compression methods
139//!
140//! ```rust
141//! # #[cfg(feature = "compress")]
142//! # {
143//! use async_sevenz::{ArchiveWriter, encoder_options};
144//!
145//! #[tokio::main]
146//! async fn main() {
147//!     let mut writer = ArchiveWriter::create_in_memory()
148//!         .await
149//!         .expect("create writer ok");
150//!     writer.set_content_methods(vec![
151//!         encoder_options::AesEncoderOptions::new("sevenz-rust".into()).into(),
152//!         encoder_options::Lzma2Options::from_level(9).into(),
153//!     ]);
154//!     writer
155//!         .push_source_path("examples/data/sample", |_| async { true })
156//!         .await
157//!         .expect("pack ok");
158//!     writer.finish().await.expect("compress ok");
159//! }
160//! # }
161//! ```
162#![cfg_attr(docsrs, feature(doc_cfg))]
163#![warn(missing_docs)]
164
165#[cfg(target_arch = "wasm32")]
166extern crate wasm_bindgen;
167
168#[cfg(feature = "compress")]
169mod encoder;
170/// Encoding options when compressing.
171#[cfg(feature = "compress")]
172pub mod encoder_options;
173mod encryption;
174mod error;
175mod reader;
176
177#[cfg(feature = "compress")]
178mod writer;
179
180pub(crate) mod archive;
181pub(crate) mod bitset;
182pub(crate) mod block;
183mod codec;
184pub(crate) mod decoder;
185
186mod time;
187mod util;
188
189use std::ops::{Deref, DerefMut};
190
191pub use archive::*;
192pub use block::*;
193pub use encryption::Password;
194pub use error::Error;
195pub use reader::{ArchiveReader, BlockDecoder};
196pub use time::NtTime;
197#[cfg(all(feature = "compress", not(target_arch = "wasm32")))]
198pub use util::compress::*;
199#[cfg(not(target_arch = "wasm32"))]
200pub use util::decompress::*;
201#[cfg(target_arch = "wasm32")]
202pub use util::wasm::*;
203#[cfg(feature = "compress")]
204pub use writer::*;
205
206/// A trait for writers that finishes the stream on drop.
207pub trait AutoFinish {
208    /// Finish writing the stream without error handling.
209    fn finish_ignore_error(self);
210}
211
212/// A wrapper around a writer that finishes the stream on drop.
213pub struct AutoFinisher<T: AutoFinish>(Option<T>);
214
215impl<T: AutoFinish> Drop for AutoFinisher<T> {
216    fn drop(&mut self) {
217        if let Some(writer) = self.0.take() {
218            writer.finish_ignore_error();
219        }
220    }
221}
222
223impl<T: AutoFinish> Deref for AutoFinisher<T> {
224    type Target = T;
225
226    fn deref(&self) -> &Self::Target {
227        self.0.as_ref().unwrap()
228    }
229}
230
231impl<T: AutoFinish> DerefMut for AutoFinisher<T> {
232    fn deref_mut(&mut self) -> &mut Self::Target {
233        self.0.as_mut().unwrap()
234    }
235}