14个版本 (9个重大更新)
0.10.1 | 2023年12月12日 |
---|---|
0.9.0 | 2023年8月22日 |
0.7.0 | 2023年7月9日 |
#90 在 过程宏
每月下载量 77次
在 rustifact_extra 中使用
75KB
1.5K SLoC
Rustifact ┃
构建脚本与主crate之间的无缝桥梁。
动机
在编译时生成计算密集型工件时,我们有多种工具可供选择:构建脚本(build.rs)、声明式宏(macro_rules!)、过程宏,以及越来越流行的const函数。然而,每种方法都有自己的挑战。
Rustifact 被设计为一个抽象层,简化了生成构建脚本的创建,这些脚本生成包含到最终二进制文件中的数据。
支持的类型
Rustifact 允许使用由数值类型(浮点数、整数、usize)、布尔值、字符串、数组、结构体和枚举组成的数据类型的 static
和 const
声明。还支持(无序和有序)集合和具有完美哈希查找的映射。
(*) 集合和映射是由出色的 phf_codegen 库提供的,但这些功能是通过 set
和 map
功能控制的。
(*) 通过 rustifact_extra crate 提供了对交错数组的支持。
使用步骤
-
在您的构建脚本中生成所需的数据。
-
对于任何从您的构建脚本导出的自定义类型(*)(不在Rust标准库中),请使用以下语法:
#[derive(ToTokenStream)]
。 -
使用任意组合的
write_X
宏导出您的数据。 -
在您的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 使用
ToTokenStream
的OutType
属性展示结构体导出 -
map 展示了如何通过完美哈希函数构建映射
更多示例,请查看crate文档中的write_X
宏。
开发状态
请注意,Rustifact处于早期开发阶段。总的来说,它不太可能带来不愉快的惊喜,尽管可能存在尚未发现的边缘情况。将来可能会发生一些破坏性变化,尽管我们尽可能保持向后兼容。
许可证
Rustifact是免费软件,并根据Mozilla公共许可证第2.0版发布。请参阅LICENSE。
依赖项
~0.5–1MB
~25K SLoC