Skip to main content

installrs/
source.rs

1//! Compile-time path-hashing and the [`source!`] macro.
2
3/// Compile-time FNV-1a 64-bit hash of a path string (backslashes normalized to forward slashes).
4///
5/// Used by the [`crate::source!`] macro.
6pub const fn source_path_hash_const(path: &str) -> u64 {
7    let bytes = path.as_bytes();
8    let mut h: u64 = 14695981039346656037;
9    let mut i = 0;
10    while i < bytes.len() {
11        let b = if bytes[i] == b'\\' { b'/' } else { bytes[i] };
12        h ^= b as u64;
13        h = h.wrapping_mul(1099511628211);
14        i += 1;
15    }
16    h
17}
18
19/// Compile-time reference to an embedded file or directory.
20///
21/// Create one with the [`crate::source!`] macro, then pass it to
22/// [`crate::Installer::file`] or [`crate::Installer::dir`].
23#[derive(Copy, Clone, Debug, PartialEq, Eq)]
24pub struct Source(pub u64);
25
26/// Produce a [`Source`] from a literal path, hashed at compile time.
27///
28/// The path string itself never appears in the final binary. Paths are
29/// relative to the project root as seen by the build tool.
30///
31/// Accepts optional build-time-only keyword arguments; the values are parsed
32/// by the build tool's scanner (not used at runtime). Supported keys:
33///
34/// - `ignore = ["glob", ...]` — extra glob patterns applied when gathering a
35///   directory, merged with the CLI-level `--ignore` list.
36/// - `features = ["name", ...]` — cargo-feature gate. The source is only
37///   embedded when at least one of the listed features is enabled via
38///   `installrs --feature <name>`.
39///
40/// ```rust,ignore
41/// i.file(installrs::source!("assets/config.toml"), "etc/myapp/config.toml")
42///     .install()?;
43/// i.dir(source!("assets", ignore = ["*.bak", "scratch"]), "assets").install()?;
44/// i.file(source!("pro.dat", features = ["pro"]), "pro.dat").install()?;
45/// ```
46#[macro_export]
47macro_rules! source {
48    ($path:literal $(, $key:ident = $val:expr)* $(,)?) => {{
49        const H: u64 = $crate::source_path_hash_const($path);
50        $crate::Source(H)
51    }};
52}