有没有办法在 Rust 库中包含二进制文件或文本文件?

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

我正在尝试创建一个库,我想在其中包含一些二进制(或文本)文件,这些文件将包含将在运行时解析的数据。

我的意图是控制这些文件,不断更新它们并在每次更新时更改库的版本。

这可以通过货物运输吗?如果是这样,我如何从我的图书馆访问这些文件?

我想到的一个解决方法是包含一些 .rs 带有结构 and/or 常量的文件,例如 &str,它将存储数据,但我发现它有点难看。

编辑:

我已将已接受的答案更改为更适合我的情况,但请查看 ,因为这可能更适合您的情况。

include_bytes! 宏似乎接近您的要求。它只给你一个字节数组的引用,所以你必须从那里开始做任何解析:

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]);
}

如果你有UTF-8内容,你可以使用include_str!, as pointed out by :

static HOST_FILE: &'static str = include_str!("/etc/hosts");

fn main() {
    println!("Hosts are:\n{}", &HOST_FILE[..42]);
}

免责声明:我在评论中提到了它,但让我在这里重申一下,因为它让我有更多 space 来详细说明。

正如 Shepmaster 所说,可以使用 include_bytes!include_str! 宏在 Rust library/executable 中逐字包含文本或二进制文件。

但是,对于你的情况,我会避免它。通过将内容的解析延迟到 运行-time:

  • 您允许构建有缺陷的工件。
  • 你招致(更多)运行-时间开销(解析时间)。
  • 你招致(更多)space 开销(解析代码)。

Rust 承认这个问题,并提供多种代码生成机制来克服这些限制:

  • 宏:如果逻辑可以编码成宏,那么可以直接包含在源文件中
  • 插件:启动宏,可以对任意逻辑进行编码并生成复杂的代码(参见 regex!
  • build.rs: 一个独立的 "Rust script" 运行ning 提前编译本身其作用是生成 .rs 文件

对于您的情况,build.rs 脚本听起来很合适:

  • 通过将解析代码移到那里,您交付了一个更轻的工件
  • 通过提前解析,您可以更快地交付工件
  • 通过提前解析,您交付了正确的工件

解析的结果可以用不同的方式编码,从函数到静态(可能 lazy_static!),因为 build.rs 可以生成任何有效的 Rust 代码。

您可以在the Cargo Documentation中查看如何使用build.rs;您会在那里找到如何将它与 Cargo 集成以及如何创建文件(以及更多)。