include_str!设置“字符串字面值”路径

8

我需要在我的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 中任何内容构造字符串字面值。我想知道是否可以从 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 还不熟悉。
2个回答

11

include_str!是一个宏,因此在编译时执行。由于编译器无法预知运行时String或某些静态变量的内容,所以您不能将include_str!String或静态变量一起使用。

但是,有一种方法可以参考相对于crate根目录的文件:您可以结合env!concat!编译时由Cargo设置的环境变量CARGO_MANIFEST_DIR来实现想要的功能。两个宏都发出字符串字面值,因此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);
}

2
我在这里还要注意一点,如果您需要包含一些动态的 Rust 代码,那么使用构建脚本也是可能的:https://doc.rust-lang.org/cargo/reference/build-scripts.html。它可以用于生成一个文件到 out 目录中,然后可以使用 include_str 包含该文件,这将在构建脚本执行后发生。 - Taywee

0

如果文件名需要动态枚举(例如包含目录中的所有文件),那么Elias Holzmann的方法也不起作用。

在这种情况下,我会将目录压缩为Zip文件,使用include_bytes!将其包含,并读取它作为Zip文件以枚举其内容并使用它们。

一个示例用例是在Webview Rust应用程序中作为桌面应用程序包含ReactJS或Vue APP的dist目录。Github中的示例代码将作为编辑后跟随。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接