include_dir/
lib.rs

1//! An extension to the `include_str!()` and `include_bytes!()` macro for
2//! embedding an entire directory tree into your binary.
3//!
4//! # Environment Variables
5//!
6//! When invoking the [`include_dir!()`] macro you should try to avoid using
7//! relative paths because `rustc` makes no guarantees about the current
8//! directory when it is running a procedural macro.
9//!
10//! Environment variable interpolation can be used to remedy this. You might
11//! want to read the [*Environment Variables*][cargo-vars] section of *The
12//! Cargo Book* for a list of variables provided by `cargo`.
13//!
14//! Most crates will want to use the `$CARGO_MANIFEST_DIR` or `$OUT_DIR`
15//! variables. For example, to include a folder relative to your crate you might
16//! use `include_dir!("$CARGO_MANIFEST_DIR/assets")`.
17//!
18//! # Examples
19//!
20//! Here is an example that embeds the `include_dir` crate's source code in a
21//! `static` so we can play around with it.
22//!
23//! ```rust
24//! use include_dir::{include_dir, Dir};
25//! use std::path::Path;
26//!
27//! static PROJECT_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR");
28//!
29//! // of course, you can retrieve a file by its full path
30//! let lib_rs = PROJECT_DIR.get_file("src/lib.rs").unwrap();
31//!
32//! // you can also inspect the file's contents
33//! let body = lib_rs.contents_utf8().unwrap();
34//! assert!(body.contains("SOME_INTERESTING_STRING"));
35//!
36//! // if you enable the `glob` feature, you can for files (and directories) using glob patterns
37//! #[cfg(feature = "glob")]
38//! {
39//!     let glob = "**/*.rs";
40//!     for entry in PROJECT_DIR.find(glob).unwrap() {
41//!         println!("Found {}", entry.path().display());
42//!     }
43//! }
44//! ```
45//!
46//! # Features
47//!
48//! This library exposes a couple feature flags for enabling and disabling extra
49//! functionality. These are:
50//!
51//! - `glob` - search for files using glob patterns
52//! - `metadata` - include some basic filesystem metadata like last modified
53//!   time. This is not enabled by default to allow for more reproducible builds
54//!   and to hide potentially identifying information.
55//! - `nightly` - enables nightly APIs like [`track_path`][track-path]
56//!   and  [`proc_macro_tracked_env`][tracked-env]. This gives the compiler
57//!   more information about what is accessed by the procedural macro, enabling
58//!   better caching. **Functionality behind this feature flag is unstable and
59//!   may change or stop compiling at any time.**
60//!
61//! # Compile Time Considerations
62//!
63//! While the `include_dir!()` macro executes relatively quickly, it expands
64//! to a fairly large amount of code (all your files are essentially embedded
65//! as Rust byte strings) and this may have a flow-on effect on the build
66//! process.
67//!
68//! In particular, including a large number or files or files which are
69//! particularly big may cause the compiler to use large amounts of RAM or spend
70//! a long time parsing your crate.
71//!
72//! As one data point, this crate's `target/` directory contained 620 files with
73//! a total of 64 MB, with a full build taking about 1.5 seconds and 200MB of
74//! RAM to generate a 7MB binary.
75//!
76//! Using `include_dir!("target/")` increased the compile time to 5 seconds
77//! and used 730MB of RAM, generating a 72MB binary.
78//!
79//! [tracked-env]: https://github.com/rust-lang/rust/issues/74690
80//! [track-path]: https://github.com/rust-lang/rust/issues/73921
81//! [cargo-vars]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
82
83#![deny(
84    elided_lifetimes_in_paths,
85    future_incompatible,
86    missing_copy_implementations,
87    missing_debug_implementations,
88    missing_docs,
89    rust_2018_idioms
90)]
91#![cfg_attr(feature = "nightly", feature(doc_cfg))]
92
93mod dir;
94mod dir_entry;
95mod file;
96
97#[cfg(feature = "metadata")]
98mod metadata;
99
100#[cfg(feature = "glob")]
101mod globs;
102
103#[cfg(feature = "metadata")]
104pub use crate::metadata::Metadata;
105
106pub use crate::{dir::Dir, dir_entry::DirEntry, file::File};
107pub use include_dir_macros::include_dir;
108
109#[doc = include_str!("../README.md")]
110#[allow(dead_code)]
111fn check_readme_examples() {}