Expand description
§Rustifact
A seamless bridge between a build script and the main crate.
§Motivation
When it comes to generating computationally intensive artifacts at compile time, we have many tools at our disposal: build scripts (build.rs), declarative macros (macro_rules!), procedural macros, and increasingly, const functions. Each of these methods, however, brings its own set of challenges.
Rustifact has been designed as an abstraction layer that simplifies the creation of build scripts that produce data for inclusion into the final binary.
§Types supported
Rustifact allows static
and const
declarations of data types composed of numeric types
(floats, ints, usize), booleans, strings, arrays, structs, and enums. Also supported are
(unordered and ordered) sets and maps with perfect-hash lookup.
(*) Sets and maps are provided with help from the excellent
phf_codegen library, though these features are gated via
the set
and map
features.
(*) Jagged array support is available via the rustifact_extra crate.
§Usage steps
-
Generate the required data in your build script.
-
#[derive(ToTokenStream)]
for any custom types(*) (not in the Rust standard library) exported from your build script. -
Export your data with any combination of the
write_X
macros. -
In the main part of your crate (within
src/
) import your data withuse_symbols
.
(*) These types should be implemented in a separate crate, so they’re usable from the build script and the main crate.
NOTE: We refer to exclusively to data in the above, but Rustifact is also capable of generating types in some situations where doing so by hand would be burdensome.
§A simple example
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"
§Development status
Please note that Rustifact is in an early development stage. Overall, it is unlikely to cause unpleasant surprises, though there may be edge cases that haven’t yet been discovered. Some breaking changes may occur in the future, though we aim to preserve backward compatibility where possible.
Modules§
- internal
- An implementation detail, exposing parts of external crates used by
rustifact
.
Macros§
- allow_
export - Setup the symbol for export from the main crate.
- export_
symbols - Export the given symbols (generated by the build script).
- init_
symbols - Import the given struct initialisation expression (generated by the build script) into scope.
- use_
symbols - Import the given symbols (generated by the build script) into scope.
- write_
array_ fn Deprecated - Write an array or vector to an array getter function.
- write_
const - Write a constant variable.
- write_
const_ array - Write an array to a const context.
- write_
consts - Write a collection of constants with a common type.
- write_
fn - Write a getter function for a heap-allocated variable.
- write_
fns - Write a collection of getter functions returning a common type.
- write_
static - Write a static variable.
- write_
static_ array - Write an array to a static context.
- write_
statics - Write a collection of static variables with a common type.
- write_
struct - Write a struct type definition.
- write_
struct_ uniform - Write a struct type definition with a single field type.
- write_
struct_ uniform_ init - Write a struct initialisation expression.
- write_
vector_ fn Deprecated - Write an array or vector to a vector getter function.
Structs§
- Map
- An immutable map with lookup via a perfect hash function.
- MapBuilder
- A compile time builder for an immutable map.
- Ordered
Map - An order-preserving immutable map with lookup via a perfect hash function.
- Ordered
MapBuilder - A compile time builder for an order-preserving immutable map.
- Ordered
Set - An order-preserving immutable set with lookup via a perfect hash function.
- Ordered
SetBuilder - A compile time builder for an order-preserving immutable set.
- Set
- An immutable set with lookup via a perfect hash function.
- SetBuilder
- A compile time builder for an immutable set.
Traits§
- ToToken
Stream - Provides a flexible interface for converting Rust’s data types into their token stream representation.
This trait is akin to
quote::ToTokens
, with a similar design, but it serves a distinct purpose.
Derive Macros§
- ToToken
Stream - Implement
ToTokenStream
for a struct or enum with components implementatingToTokenStream
.