rar_stream/lib.rs
1//! # rar-stream
2//!
3//! A high-performance RAR archive streaming library for Rust, Node.js, and browsers.
4//!
5//! This library provides streaming access to files within RAR archives, optimized for
6//! video streaming with fast seeking via binary search. It supports both RAR4 (1.5-4.x)
7//! and RAR5 (5.0+) formats with full decompression and optional encryption support.
8//!
9//! ## Features
10//!
11//! | Feature | Default | Description |
12//! |---------|---------|-------------|
13//! | `crypto` | No | Encrypted archive support (AES-256 for RAR5, AES-128 for RAR4) |
14//! | `napi` | No | Node.js native bindings via napi-rs (includes async I/O) |
15//! | `wasm` | No | Browser WebAssembly bindings |
16//!
17//! ## Supported Formats
18//!
19//! | Format | Versions | Compression | Encryption |
20//! |--------|----------|-------------|------------|
21//! | RAR4 | 1.5-4.x | LZSS, PPMd | AES-128-CBC (SHA-1 KDF) |
22//! | RAR5 | 5.0+ | LZSS + filters | AES-256-CBC (PBKDF2-HMAC-SHA256) |
23//!
24//! ## Architecture
25//!
26//! The library is organized into layers:
27//!
28//! ```text
29//! ┌─────────────────────────────────────────────────────┐
30//! │ Application Layer (async feature) │
31//! │ RarFilesPackage → InnerFile → read_to_end() │
32//! ├─────────────────────────────────────────────────────┤
33//! │ Parsing Layer │
34//! │ MarkerHeader → ArchiveHeader → FileHeader │
35//! ├─────────────────────────────────────────────────────┤
36//! │ Decompression Layer │
37//! │ Rar29Decoder (RAR4) / Rar5Decoder (RAR5) │
38//! ├─────────────────────────────────────────────────────┤
39//! │ Crypto Layer (crypto feature) │
40//! │ Rar4Crypto (AES-128) / Rar5Crypto (AES-256) │
41//! └─────────────────────────────────────────────────────┘
42//! ```
43//!
44//! ## Quick Start
45//!
46//! ### High-Level API (requires `napi` feature for Node.js)
47//!
48//! ```rust,ignore
49//! use rar_stream::{RarFilesPackage, ParseOptions, LocalFileMedia, FileMedia};
50//! use std::sync::Arc;
51//!
52//! #[tokio::main]
53//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
54//! // Open a RAR archive
55//! let file: Arc<dyn FileMedia> = Arc::new(LocalFileMedia::new("archive.rar")?);
56//! let package = RarFilesPackage::new(vec![file]);
57//!
58//! // Parse and list files
59//! let files = package.parse(ParseOptions::default()).await?;
60//! for f in &files {
61//! println!("{}: {} bytes", f.name, f.length);
62//! }
63//!
64//! // Read file content (automatically decompresses)
65//! let content = files[0].read_to_end().await?;
66//! Ok(())
67//! }
68//! ```
69//!
70//! ### Low-Level Decompression (no features required)
71//!
72//! ```rust
73//! use rar_stream::Rar29Decoder;
74//!
75//! // Create a decoder for RAR4 LZSS data
76//! let mut decoder = Rar29Decoder::new();
77//!
78//! // Decompress raw compressed data (obtained from file header)
79//! // let decompressed = decoder.decompress(&compressed_data, expected_size)?;
80//! ```
81//!
82//! ## Encrypted Archives
83//!
84//! With the `crypto` feature, you can read encrypted archives:
85//!
86//! ```rust,ignore
87//! use rar_stream::{RarFilesPackage, ParseOptions};
88//!
89//! let opts = ParseOptions {
90//! password: Some("secret".to_string()),
91//! ..Default::default()
92//! };
93//! let files = package.parse(opts).await?;
94//!
95//! // Content is automatically decrypted and decompressed
96//! let content = files[0].read_decompressed().await?;
97//! ```
98//!
99//! ## Error Handling
100//!
101//! All operations return [`Result<T, RarError>`]. Common errors include:
102//!
103//! - [`RarError::InvalidSignature`] - Not a valid RAR file
104//! - [`RarError::PasswordRequired`] - Encrypted archive, no password provided
105//! - [`RarError::DecryptionFailed`] - Wrong password or corrupt data
106//! - [`RarError::DecompressionNotSupported`] - Unsupported compression method
107//!
108//! ## Module Overview
109//!
110//! - [`error`] - Error types for all operations
111//! - [`parsing`] - RAR header parsing (both RAR4 and RAR5)
112//! - [`decompress`] - Decompression algorithms (LZSS, PPMd, filters)
113//! - [`crypto`] - Encryption/decryption (requires `crypto` feature)
114//! - [`formats`] - Low-level format constants and utilities
115//!
116//! ## Performance Notes
117//!
118//! - **Streaming**: Files are read on-demand, not loaded entirely into memory
119//! - **Binary search**: Chunk lookup uses binary search for O(log n) seeking
120//! - **Zero-copy parsing**: Headers are parsed without unnecessary allocations
121//! - **Cached decompression**: Decompressed data is cached for repeated reads
122//!
123//! ## Browser/WASM Usage
124//!
125//! With the `wasm` feature, the library compiles to WebAssembly for browser use.
126//! See the npm package documentation for JavaScript API details.
127
128// Note: unsafe_code = "warn" in Cargo.toml allows targeted unsafe for performance
129// All unsafe blocks should be minimal and well-documented with SAFETY comments
130
131mod crc32;
132#[cfg(feature = "crypto")]
133pub mod crypto;
134pub mod decompress;
135pub mod error;
136mod file_media;
137pub mod formats;
138pub mod parsing;
139
140// Async modules (require 'napi' feature)
141#[cfg(feature = "napi")]
142mod inner_file;
143#[cfg(feature = "napi")]
144mod rar_file_chunk;
145#[cfg(feature = "napi")]
146mod rar_files_package;
147
148#[cfg(feature = "napi")]
149mod napi_bindings;
150
151#[cfg(feature = "wasm")]
152mod wasm_bindings;
153
154pub use error::RarError;
155pub use file_media::{LocalFileMedia, ReadInterval};
156
157#[cfg(feature = "napi")]
158pub use file_media::FileMedia;
159#[cfg(feature = "napi")]
160pub use inner_file::{ChunkMapEntry, InnerFile, InnerFileStream, StreamChunkInfo};
161#[cfg(feature = "napi")]
162pub use rar_file_chunk::RarFileChunk;
163#[cfg(feature = "napi")]
164pub use rar_files_package::{ParseOptions, RarFilesPackage};
165
166// Re-export decompression types
167pub use decompress::{CompressionMethod, DecompressError, Rar29Decoder};
168
169// Re-export NAPI bindings when feature is enabled
170#[cfg(all(feature = "napi", not(feature = "wasm")))]
171pub use napi_bindings::*;
172
173// Re-export WASM bindings when feature is enabled
174#[cfg(all(feature = "wasm", not(feature = "napi")))]
175pub use wasm_bindings::*;