我必须在我的Rust二进制文件中发布json
和toml
文件。它是一个独立的应用程序,人们不想在运行时传入配置文件。
include_str!
做我想做的事。我可以写:
static SETTINGS_FILE_STR: &str = include_str!(r"../my_config/settings.toml");
是否有比r"../my_config/settings.toml"
更好的方法来写文件路径?
我似乎不能从use std::path::{Path, PathBuf};
或env
内部的任何东西构建string literal
。我想知道我是否可以从cargo.toml
文件中读取一些东西。没有运气。
我总是按:
error: argument must be a string literal
--> src/main.rs:23:42
|
23 | static SETTINGS_STR: &str = include_str!(FANCY_PATH_TO_TOML_FILE);
| ^^^^^^^^^^^^
我不能做以下操作,因为String
不是字符串文字:
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()
}
如果这是C/Objective-C,我可以使用构造函数或类函数来实现我想要的。你可能已经猜到了,我是Rust新手。
include_str!
是一个宏,因此在编译时执行。因为编译器在运行时还不能知道String
或某个静态变量的内容,所以不能将include_str!
与String
或静态变量一起使用。
然而,有一个相对于您的crate根引用文件的解决方案:您可以将env!
和concat!
与环境变量CARGO_MANIFEST_DIR
(在编译时由Cargo设置)组合起来做您想做的事情。这两个宏都输出字符串字面值,所以include_str!
对它们很满意。
这将在您的crate根目录中输出my_config/settings.toml
的内容:
static SETTINGS_STR: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/my_config/settings.toml"));
fn main() {
println!("The config: {}", SETTINGS_STR);
}
如果文件名是动态枚举的(例如包含目录中的所有文件),那么Elias Holzmann的方法也将不起作用。
在这种情况下,我将压缩目录,将其包含为include_bytes!
,然后将其作为Zip文件读取,以枚举其内容并使用它们。
一个示例用例是在webview rust应用程序中包含一个ReactJS或Vue应用程序的dist目录,作为桌面应用程序。github中的示例代码将作为编辑。