Is there a way to include binary or text files in the Rust library?

I am trying to create a library, and I want to include several binary (or text) files in it that will have data that will be processed at runtime.

My intention is to control these files, constantly update them and change the library version in each update.

Is this possible through cargo? If so, how can I access these files from my library?

The workaround I was thinking about is to include some .rs files with structs and / or constants like &str that will store the data, but I find it kind of ugly.

EDIT:

I changed the accepted answer to one that suits my case more, but look at Shepmaster's answer , as this might be more appropriate in your case.

+5
source share
2 answers

Disclaimer: I mentioned this in a comment, but let me rename it here as it gives me more development options.

As Shepmaster said, you can include text or a binary file in the Rust library / executable using include_bytes! macros include_bytes! and include_str! .

In your case, however, I would avoid this. Putting off parsing content for runtime:

  • You allow the creation of a defective artifact.
  • you bear (more) overhead at runtime (parsing time).
  • you bear (more) overhead (parsing code).

Rust confirms this problem and offers several code generation mechanisms designed to overcome these limitations:

  • macros: if the logic can be encoded into a macro, then it can be directly included in the source file
  • plugins: activated macros that can encode any arbitrary logic and generate complex code (see regex! )
  • build.rs : an independent "Rust script" that runs ahead of the compilation itself, the role of which is to generate .rs files

In your case, the build.rs script sounds good:

  • by moving the parsing code there, you get a lighter artifact
  • using parsing ahead of time, you get a faster artifact
  • by parsing in advance, you deliver the correct artifact

The result of your analysis can be encoded in different ways: from functions to statics (possibly lazy_static! ), Because build.rs can generate any valid Rust code.

You can see how to use build.rs in the build.rs Documentation ; You will find there how to integrate it with Cargo and how to create files (and much more).

+8
source

Macro include_bytes! seems close to what you want. It gives you only a reference to an array of bytes, so you will need to do any parsing, starting with this:

 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 indicated by Benjamin Lindley :

 static HOST_FILE: &'static str = include_str!("/etc/hosts"); fn main() { println!("Hosts are:\n{}", &HOST_FILE[..42]); } 
+6
source

Source: https://habr.com/ru/post/1232142/


All Articles