include_packed/
lib.rs

1//! Include large, compressed files in your binary without the high compile time cost.
2//!
3//! This crate provides the [`include_packed!`] macro as an efficient alternative to
4//! `std::include_bytes!`. It combines the fast compile-time approach of `include-blob`
5//! with the binary size reduction of `zstd` compression.
6//!
7//! ## How It Works
8//!
9//! Instead of embedding file contents directly into your source code, this crate
10//! processes files in a build script.
11//!
12//! 1.  **Build Script:** You use the [`build::Config`] builder in your `build.rs` script. For native
13//!     targets, it reads your asset files, compresses them with `zstd`, and creates
14//!     linkable object files.
15//! 2.  **Macro Expansion:** The `include_packed!` macro in your code expands to an
16//!     expression that links to the compressed data (on native) or embeds the compressed
17//!     data directly (on Wasm).
18//! 3.  **Runtime:** At runtime, the expression decompresses the data and returns it
19//!     as a `Vec<u8>`. Decompression is performed on each call.
20//!
21//! This method significantly reduces compile times for projects with large binary assets
22//! and keeps the final executable size smaller.
23//!
24//! ## Usage
25//!
26//! 1. Add `include_packed` to your `Cargo.toml`. The `build` feature is required for
27//!    build-dependencies.
28//!
29//! ```toml
30//! [dependencies]
31//! include_packed = "0.1.0"
32//!
33//! [build-dependencies]
34//! include_packed = { version = "0.1.0", features = ["build"] }
35//! ```
36//!
37//! 2. Create a `build.rs` file in your project root to prepare the assets.
38//!
39//! ```no_run
40//! // build.rs
41//! // This handles all platform-specific logic automatically.
42//! include_packed::Config::new("assets")
43//!   .level(10) // Set a custom zstd compression level (optional)
44//!   .build()
45//!   .expect("Failed to pack assets");
46//! ```
47//!
48//! 3. Use the macro in your code to include an asset.
49//!
50//! ```no_run
51//! // src/main.rs
52//! use include_packed::include_packed;
53//!
54//! // This returns a Vec<u8> with the decompressed file content.
55//! let data: Vec<u8> = include_packed!("assets/my_file.txt");
56//! println!("Decompressed data is {} bytes long.", data.len());
57//!
58//! ```
59
60#![doc(html_root_url = "https://docs.rs/include_packed")]
61
62// Re-export the procedural macro.
63pub use include_packed_macros::include_packed;
64
65//
66// ===== RUNTIME CODE =====
67//
68
69/// Decompresses data that was compressed at compile time.
70///
71/// This function is an implementation detail of the [`include_packed!`] macro and is not
72/// intended to be called directly by user code. Its signature is not guaranteed to be stable.
73///
74/// # Panics
75///
76/// Panics if the provided data is not valid zstd-compressed data. This indicates a bug in
77/// `include_packed` itself, as the data should always be valid if generated correctly.
78#[doc(hidden)]
79#[track_caller]
80#[must_use]
81pub fn decompress(compressed_data: &'static [u8]) -> Vec<u8> {
82    zstd::decode_all(compressed_data).expect(
83        "BUG: include_packed: failed to decompress compile-time data. This indicates a bug in the crate.",
84    )
85}
86
87//
88// ===== BUILD-TIME CODE =====
89//
90
91#[cfg(feature = "build")]
92mod build;
93#[cfg(feature = "build")]
94pub use build::Config;