rar-stream 5.3.2

High-performance RAR streaming library with optional async, crypto, NAPI, and WASM support
Documentation
# Architecture

## Overview

rar-stream is a RAR archive library written in Rust with bindings for Node.js (NAPI) and browsers (WASM). The core library has **zero dependencies** — all dependencies are optional via Cargo features.

## Layers

```text
┌─────────────────────────────────────────────────────────────┐
│  Bindings                                                   │
│  napi_bindings.rs (Node.js)  │  wasm_bindings.rs (Browser)  │
├─────────────────────────────────────────────────────────────┤
│  Orchestration (async feature)                              │
│  RarFilesPackage → InnerFile → FileMedia                    │
├─────────────────────────────────────────────────────────────┤
│  Parsing                                                    │
│  MarkerHeader → ArchiveHeader → FileHeader                  │
├─────────────────────────────────────────────────────────────┤
│  Decompression                                              │
│  Rar29Decoder (RAR4) │ Rar5Decoder (RAR5)                   │
├─────────────────────────────────────────────────────────────┤
│  Crypto (crypto feature)                                    │
│  Rar4Crypto (AES-128-CBC) │ Rar5Crypto (AES-256-CBC)        │
└─────────────────────────────────────────────────────────────┘
```

## Module Structure

```
src/
├── lib.rs                  # Public API, re-exports, crate docs
├── parsing/                # RAR header parsing
│   ├── marker_header.rs    # RAR4/RAR5 signature detection
│   ├── rar4/               # RAR4 archive + file headers
│   └── rar5/               # RAR5 archive + file headers
├── decompress/             # Decompression engines
│   ├── mod.rs              # CompressionMethod enum, shared types
│   ├── rar29.rs            # RAR4 LZSS + Huffman decoder
│   ├── rar5/               # RAR5 LZSS + filters pipeline
│   ├── ppm/                # PPMd model (RAR4)
│   └── filters/            # VM filters (E8E9, delta, ARM, etc.)
├── crypto/                 # Encryption/decryption (crypto feature)
│   ├── rar4_crypto.rs      # AES-128-CBC, SHA-1 KDF
│   └── rar5_crypto.rs      # AES-256-CBC, PBKDF2-HMAC-SHA256
├── file_media.rs           # FileMedia trait + LocalFileMedia
├── rar_files_package.rs    # Multi-volume orchestration
├── rar_file_chunk.rs       # Byte ranges across volumes
├── inner_file.rs           # File inside archive, streaming reads
├── napi_bindings.rs        # Node.js NAPI exports
├── wasm_bindings.rs        # Browser WASM exports
├── formats/                # RAR format constants
├── error.rs                # RarError enum
└── crc32.rs                # CRC32 table (no-dep)
```

## Data Flow

### Parsing

```
Raw bytes → MarkerHeaderParser::detect_version()
         → ArchiveHeaderParser (RAR4 or RAR5)
         → FileHeaderParser → Vec<FileHeader>
```

### Reading a File

```
RarFilesPackage::new(volumes)
  → sort volumes (.rar → .r00 → .r01...)
  → parse headers across all volumes
  → build chunk map (which bytes in which volume)

InnerFile::read_to_end()
  → resolve chunks via binary search
  → FileMedia::read_range() for each chunk
  → decrypt (if encrypted, crypto feature)
  → decompress (if compressed)
  → return Vec<u8>
```

### Decompression Pipeline (RAR5, parallel feature)

```
Compressed blocks → Huffman decode → LZ match copy → Filter pipeline → Output
                                                      ├── E8E9 (x86)
                                                      ├── Delta
                                                      └── ARM
```

With the `parallel` feature, RAR5 decompression uses a producer-consumer pipeline:
- **Producer thread**: Huffman decoding + LZ match copy
- **Consumer thread**: Filter application + output assembly

## Feature Gates

```
default = []

async   = [tokio]               # Async file I/O, RarFilesPackage, InnerFile
crypto  = [aes, cbc, pbkdf2,    # AES encryption support
           sha2, sha1]
parallel = [rayon, crossbeam]   # Multi-threaded RAR5 decompression
napi    = [napi, napi-derive,   # Node.js bindings
           async, parallel]
wasm    = [wasm-bindgen, js-sys] # Browser bindings
```

## Multi-Volume Ordering

Volumes are sorted by extension:
1. `.rar` (main volume, always first)
2. `.r00`, `.r01`, `.r02`, ... (continuation volumes)
3. `.s00`, `.s01`, ... (overflow after `.r99`)

File data can span multiple volumes — the chunk map tracks byte ranges across volumes.

## Key Design Decisions

- **Range reads are inclusive**: `{ start: 0, end: 10 }` returns 11 bytes
- **Decompression is cached**: Once decompressed, the result is stored in the `InnerFile`
- **Binary search for seeking**: Chunk lookup is O(log n) for video streaming use cases
- **Zero-copy parsing**: Headers are parsed from borrowed byte slices, no unnecessary allocations
- **Unsafe in hot paths**: Performance-critical loops use unsafe with SAFETY comments, validated by Miri