包含_str!设置“字符串文字”路径

rus*_*net 8 rust rust-cargo

我必须在 Rust 二进制文件中发送一个json和一个文件。toml它是一个独立的应用程序,人们不想在运行时传递配置文件。

include_str!做我想做的事。我可以写:

static SETTINGS_FILE_STR: &str = include_str!(r"../my_config/settings.toml");
Run Code Online (Sandbox Code Playgroud)

有没有比 更好的方法来写入文件路径r"../my_config/settings.toml"

我似乎无法从orstring literal内部的任何内容构造 a 。我想知道是否可以从文件中读取一些内容。没有运气。use std::path::{Path, PathBuf};envcargo.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);
   |                                          ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

我无法执行以下操作,因为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()
}
Run Code Online (Sandbox Code Playgroud)

如果这是 C / Objective-C,我可以使用构造函数或类函数来实现我想要的。正如您可能已经猜到的,我是 Rust 新手。

sk_*_*ant 11

include_str!是一个宏,因此在编译时执行。由于编译器在运行时尚无法知道 a 或某个 static 变量的内容String,因此不能include_str!与 aString或 a static 变量一起使用。

但是,有一个解决方法可以引用相对于您的板条箱根目录的文件:您可以将env!concat!环境变量CARGO_MANIFEST_DIR(由 Cargo 在编译时设置)结合起来来执行您想要的操作。这两个宏都会发出字符串文字,所以include_str!对它们很满意。

这将输出您的板条箱根目录中的内容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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我还要在这里指出,如果您需要 include_str! 一些动态 Rust,也可以通过构建脚本实现:https://doc.rust-lang.org/cargo/reference/build-scripts.html。它可用于在 out 目录中生成一个文件,然后将该文件包含在 include_str 中,这将在构建脚本执行后发生。 (2认同)