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}