I have to ship a json and a toml file inside of my Rust binary. It is a standalone app and people don't want to pass in config files at run-time.
include_str! does what I want. I can write:
static SETTINGS_FILE_STR: &str = include_str!(r"../my_config/settings.toml");
Is there a better way to write the file path than r"../my_config/settings.toml"?
I can't seem to construct a string literal from anything inside of use std::path::{Path, PathBuf}; or env. I wondered if I could read something out of the cargo.toml file. No luck.
I always hit:
error: argument must be a string literal
--> src/main.rs:23:42
|
23 | static SETTINGS_STR: &str = include_str!(FANCY_PATH_TO_TOML_FILE);
| ^^^^^^^^^^^^
I can't do the following, as String is not a string literal:
fn get_config_path() -> String {
let root_dir = project_root::get_project_root().with_context(|| format!("Failed to get project root directory"))?;
const path: PathBuf = root_dir.join("my_config/settings.toml");
path.to_string()
}
If this was C / Objective-C, I could use a constructor or Class functions to achieve what I wanted. As you may have guessed, I am new to Rust.
include_str! is a macro and as such executed at compile time. Because the compiler can't yet know what will be the content of the String or some static variable at runtime, you can't use include_str! with a String or a static variable.
However, there is a workaround for referencing files relative to your crate root: You can combine env! and concat! with the environment variable CARGO_MANIFEST_DIR (set by Cargo at compile time) to do what you want. Both macros emit string literals, so include_str! is happy with them.
This outputs the content of my_config/settings.toml inside your crate root:
static SETTINGS_STR: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/my_config/settings.toml"));
fn main() {
println!("The config: {}", SETTINGS_STR);
}
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