14个版本 (9个重大更新)

0.10.1 2023年12月12日
0.9.0 2023年8月22日
0.7.0 2023年7月9日

#90过程宏

Download history 6/week @ 2024-03-30 1/week @ 2024-05-25

每月下载量 77次
rustifact_extra 中使用

MPL-2.0 许可证

75KB
1.5K SLoC

Rustifact ┃ 构建状态 最新版本 docs

构建脚本与主crate之间的无缝桥梁。

动机

在编译时生成计算密集型工件时,我们有多种工具可供选择:构建脚本(build.rs)、声明式宏(macro_rules!)、过程宏,以及越来越流行的const函数。然而,每种方法都有自己的挑战。

Rustifact 被设计为一个抽象层,简化了生成构建脚本的创建,这些脚本生成包含到最终二进制文件中的数据。

支持的类型

Rustifact 允许使用由数值类型(浮点数、整数、usize)、布尔值、字符串、数组、结构体和枚举组成的数据类型的 staticconst 声明。还支持(无序和有序)集合和具有完美哈希查找的映射。

(*) 集合和映射是由出色的 phf_codegen 库提供的,但这些功能是通过 setmap 功能控制的。

(*) 通过 rustifact_extra crate 提供了对交错数组的支持。

使用步骤

  1. 在您的构建脚本中生成所需的数据。

  2. 对于任何从您的构建脚本导出的自定义类型(*)(不在Rust标准库中),请使用以下语法:#[derive(ToTokenStream)]

  3. 使用任意组合的write_X宏导出您的数据。

  4. 在您的crate的主要部分(在src/内)使用use_symbols导入您的数据。

(*) 这些类型应在单独的crate中实现,以便它们可以从构建脚本和主crate中使用。

注意:在上文中,我们专指数据,但Rustifact在某些情况下也能生成类型,这些情况下手动生成会很繁琐。

一个简单的例子

build.rs

use rustifact::ToTokenStream;

fn main() {
    // Write a constant of type Option<(i32, i32)>
    let a = Some((1, 2));
    rustifact::write_const!(CONST_A, Option<(i32, i32)>, &a);
    // Write a static variable of type &'static str. Strings map to static string slices.
    let b = format!("Hello {}", "from Rustifact");
    rustifact::write_static!(STATIC_B, &'static str, &b);
    // Write a getter function returning Vec<Vec<i32>>
    let c = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
    rustifact::write_fn!(get_c, Vec<Vec<i32>>, &c);
    // Write a static array of i32 with dimension two.
    let arr1: [[i32; 3]; 3] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    rustifact::write_static_array!(ARRAY_1, i32 : 2, &arr1);
    // Write a const array of f32 with dimension one.
    let arr2: [f32; 3] = [1.1, 1.2, 1.3];
    rustifact::write_const_array!(ARRAY_2, f32 : 1, &arr2);
    // or equivalently: rustifact::write_const_array!(ARRAY_2, f32, &arr2);
}

src/main.rs

rustifact::use_symbols!(CONST_A, STATIC_B, get_c, ARRAY_1, ARRAY_2);

fn main() {
    assert!(CONST_A == Some((1, 2)));
    assert!(STATIC_B == "Hello from Rustifact");
    assert!(get_c() == vec![vec![1], vec![2, 3], vec![4, 5, 6]]);
    assert!(ARRAY_1 == [[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
    assert!(ARRAY_2 == [1.1, 1.2, 1.3]);
}

Cargo.toml

[package]
# ...

[build-dependencies]
rustifact = "0.10"

[dependencies]
rustifact = "0.10"

更多示例

  • array4d 使用write_static_array!生成并导出4维数组

  • city_data 使用write_static_array!生成并导出1维数组

  • coords 展示了如何使用自定义类型与#[derive(ToTokenStream)].

  • html_tags 使用write_statics!导出大量单个常量

  • out_type 使用ToTokenStreamOutType属性展示结构体导出

  • map 展示了如何通过完美哈希函数构建映射

更多示例,请查看crate文档中的write_X宏。

开发状态

请注意,Rustifact处于早期开发阶段。总的来说,它不太可能带来不愉快的惊喜,尽管可能存在尚未发现的边缘情况。将来可能会发生一些破坏性变化,尽管我们尽可能保持向后兼容。

许可证

Rustifact是免费软件,并根据Mozilla公共许可证第2.0版发布。请参阅LICENSE

依赖项

~0.5–1MB
~25K SLoC