#directory #path #macro #binary #hash-map #include-dir #directory-tree

include-dir-macro

提供宏以将文件目录树包含在编译的二进制文件中

1个不稳定版本

0.2.0 2020年1月2日

#1610进程宏

每月39次下载

Apache-2.0

16KB
79

include-dir-macro

快速开始

使用夜间工具链,将以下内容添加到您的Cargo.toml中

[dependencies]
include-dir-macro = "0.2"

然后在您的crate根目录中(在main.rslib.rs中),添加以下内容

#![feature(proc_macro_hygiene)]

use include_dir_macro::include_dir;

最后,您可以按以下方式调用宏

include_dir!("path/to/directory");

如果路径是相对路径,它将被解释为从运行cargorustc的目录开始的相对路径

描述

提供了一个include_dir!()宏,该宏返回一个映射给定目录中的文件到文件内容的HashMap<PathBuf, &'static [u8]>,这些内容存储在构建的可执行文件中的静态字节数组中。给定一个如下结构的crate

/root
+-Cargo.toml
+-src/
| \-main.rs
|   
|       #[feature(proc_macro)]
|       extern crate include_dir_macro;
|       fn main() { 
|           let stat = include_dir!("static");
|       }
|   
\-static/
  +-this
  |
  |     ABC
  |
  +-that.html
  |
  |     <p>123</p>
  |
  \-path/
    \-to/
      \-theother.txt

            Do 
            re
            mi.

stat的值将与main.rs包含的值相同

use std::collections::HashMap;
use std::path::PathBuf

fn main() {
    let stat = HashMap::new()
    stat.insert(PathBuf::from("this"), b"ABC\n");
    stat.insert(PathBuf::from("that.html"), b"<p>123</p>\n");
    stat.insert(PathBuf::from("path/to/theother.txt"), b"Do\nre\nmi.\n");
}

理由

Rust默认提供了一个名为include_bytes!()的宏,该宏在编译时将文件内容加载到静态字节数组中。然后,内容生活在二进制文件中,不需要进一步访问文件系统。我认为这可以用于捆绑整个目录,例如,将整个网站捆绑为静态二进制文件,其中包含所有相关的图片、样式表和脚本。

include_bytes!()在用例中的一个缺点是它只对作为字符串字面量指定的路径操作,因此要用于整个目录,就必须手动添加每个文件。我看到了两种绕过这个问题的方法

一种方法是在crate的build.rs脚本中包含代码生成,该脚本遍历包含的目录,并为每个文件添加一个include_str。此方法由另一个名为include_dir的crate支持,但我希望采用include_bytes!()宏的易于使用的简洁性。这需要使用过程宏,这反过来又意味着它目前(截至Rust 1.40)只能在nightly版本上运行。

依赖关系

~1.7–4MB
~78K SLoC