write_struct_uniform_init

Macro write_struct_uniform_init 

Source
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 with use_symbols.
  • $id_vals: An identifier alias for this assignment of field values. Can only ever be referenced as the second parameter to init_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 to write_statics! (or write_consts!) in crate A’s build script, followed by use_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"));
}