I am trying to create a library and I want to include some binary (or text) files in it that will have data which will be parsed at runtime.
My intention is to have control over these files, update them constantly and change the version of the library in each update.
Is this possible via cargo? If so, how can I access these files from my library?
A workaround I thought of is to include some .rs
files with structs and/or constants like &str
which will store the data but I find it kind of ugly.
EDIT:
I have changed the accepted answer to the one that fits more my case, however take a look at Shepmaster's answer as this can be more suitable in your case.
To include code of such external libraries, you have to include it as an extern crate. And to make your life easier, you really want to use Cargo! Now copy all the contents from include_me.rs into lib.rs (it is just convention to call the root file of a library project lib.rs ).
A binary crate is an executable project that has a main() method. A library crate is a group of components that can be reused in other projects.
A binary file is one that does not contain text. It is used to store data in the form of bytes, which are typically interpreted as something other than textual characters. These files usually contain instructions in their headers to determine how to read the data stored in them.
Disclaimer: I mentioned it in a comment, but let me re-iterate here, as it gives me more space to elaborate.
As Shepmaster said, it is possible to include text or binary verbatim in a Rust library/executable using the include_bytes!
and include_str!
macros.
In your case, however, I would avoid it. By deferring the parsing of the content to run-time:
Rust acknowledges this issue, and offers multiple mechanisms for code generation destined to overcome those limitations:
regex!
)build.rs
: an independent "Rust script" running ahead of the compilation proper whose role is to generate .rs
filesIn your case, the build.rs
script sounds like a good fit:
The result of your parsing can be encoded in different ways, from functions to statics (possibly lazy_static!
), as build.rs
can generate any valid Rust code.
You can see how to use build.rs
in the Cargo Documentation; you'll find there how to integrate it with Cargo and how to create files (and more).
The include_bytes!
macro seems close to what you want. It only gives you a reference to a byte array though, so you'd have to do any parsing starting from that:
static HOST_FILE: &'static [u8] = include_bytes!("/etc/hosts");
fn main() {
let host_str = std::str::from_utf8(HOST_FILE).unwrap();
println!("Hosts are:\n{}", &host_str[..42]);
}
If you have UTF-8 content, you can use include_str!
, as pointed out by Benjamin Lindley:
static HOST_FILE: &'static str = include_str!("/etc/hosts");
fn main() {
println!("Hosts are:\n{}", &HOST_FILE[..42]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With