macro_rules! write_struct_uniform_init {
($id_struct:ident, $id_vals:ident, $t:ty, $ids_vals:expr) => { ... };
}Expand description
Write a struct initialisation expression.
Makes the struct initialisation expression available for import into the main crate via use_symbols.
§Parameters
$id_struct: the name of the struct type, and the identifier by which it is referred when importing withuse_symbols.$id_vals: An identifier alias for this assignment of field values. Can only ever be referenced as the second parameter toinit_symbols!.$t: the type of all fields of this struct$ids_vals: The list of type&[(I, V)]where I is the field’s identifier having type String or &str, and V is the value (of type $t) to assign to the field.
§Notes
Before using write_struct_uniform! carefully consider all other approaches.
Defining a struct in the usual way should be preferred when this is possible.
§Some use cases
- Generation of wrapper APIs
- Dependency injection, possibly in combination with
write_statics!. Suppose that crate A depends on crate B. The build script of crate A generates certain constants C1, …, Cn.write_struct_uniform!is used to create a type T with fields that can be instantiated with the constants C1, …, Cn. Functions (say) in crate B can be called with a parameter of type T, allowing crate B access to the constants C1, …, Cn even though crate B is a dependency of crate A. If access to C1, …, Cn is desired in crate A or other crates depending on crate A, make a suitable call towrite_statics!(orwrite_consts!) in crate A’s build script, followed byuse_symbols!.
§Example
build.rs
use rustifact::ToTokenStream;
fn main() {
let foo_fields = vec![(true, "field_a"), (true, "field_b"), (false, "field_c")];
let foo_vals = vec![
("field_a", (0u32, "abc")),
("field_b", (1u32, "def")),
("field_c", (2u32, "ghi")),
];
rustifact::write_struct_uniform!(public, Foo, (u32, &'static str), &foo_fields);
rustifact::write_struct_uniform_init!(Foo, Init, (u32, &'static str), &foo_vals);
}src/main.rs
rustifact::use_symbols!(Foo);
// Bring the Foo type into scope
static FOO_INIT: Foo = rustifact::init_symbols!(Foo, Init);
// The above line is equivalent to the declaration:
//
// static FOO_INIT: Foo = Foo {
// field_a: (0, "abc"),
// field_b: (1, "def"),
// field_c: (2, "ghi"),
// }
fn main() {
assert!(FOO_INIT.field_a == (0, "abc"));
assert!(FOO_INIT.field_b == (1, "def"));
assert!(FOO_INIT.field_c == (2, "ghi"));
}