I was looking for a crate for embedding an entire directory tree into an executable to make deployment easier, but couldn't find anything which worked the way I wanted it to... So I made my own.
At the moment you need to use a build script, but when proc_macros
become stable I'll be creating an include_dir!()
macro to go alongside include_str!()
and include_bytes!()
.
To embed a directory and its contents into your binary, you'll need to add the
following to your build.rs
script.
extern crate include_dir;
use std::env;
use std::path::Path;
use include_dir::include_dir;
fn main() {
let outdir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&outdir).join("assets.rs");
include_dir("assets")
.as_variable("SRC")
.to_file(dest_path)
.unwrap();
}
The generated code comes with doc-comments to make discovering how to use it easier, otherwise check out the integration tests directory.
Let me know what you think
9 Likes
... this is a thing I will need very soon, and so I'm extremely excited that you've made it! I'll be checking it out in the near future
Dumb question, but does any resource include images, audio files, or even other binary files?
RustProjectRoot
└───src
└───Main.rs
└───Resources
├───HappyPicture.png
├───SomethingElse.so
└───Audio.flac
Would I add the Resources folder as an 'asset' in build.rs
and then reference each file or folder similar to the CI examples you added?
I think this is a really awesome idea, thanks for your contribution! If what I think turns out to be true, I could definitely see myself using this in the future.
Internally it'll look at everything in the directory you point it at and store each file as
pub struct File {
pub name: &'static str,
pub contents: &'static [u8],
}
Therefore it shouldn't matter whether your "Resources" directory contains text files, images, or even other binaries. They all just get stored as a bunch of bytes.
I added a couple convenience methods to make accessing the resources easier. Say you embedded that "Resources" directory under the variable RESOURCES
, you can do something like this
let happy_picture = RESOURCES.find("HappyPicture.png");
or if you want to iterate over each thing in the "Resources" directory
for entry in RESOURCES.walk() {
println!("{}", entry.name());
}
1 Like