generic-array-struct
An attribute proc macro to convert structs with named fields of the same generic type into a single-array-field tuple struct with array-index-based accessor and mutator methods.
MSRV
rustc 1.64.0
(const fn
, workspace = true
)
Example Usage
use generic_array_struct;
expands to
;
// consts are exported with prefix instead of as associated consts
// so that we dont need turbofish e.g. `Cartesian::<f32>::IDX_X`
pub const CARTESIAN_LEN: usize = 2;
pub const CARTESIAN_IDX_X: usize = 0;
pub const CARTESIAN_IDX_Y: usize = 1;
Usage Notes
Declaration Order
Because this attribute modifies the struct definition, it must be placed above any derive attributes or attributes that use the struct definition
WRONG ❌
use generic_array_struct;
// Fails to compile because #[generic_array_struct] is below #[derive] attribute
RIGHT ✅
use generic_array_struct;
Field Visibility
All methods have the same visibility as that of the originally declared field in the struct.
use Cartesian;
// fails to compile because [`Cartesian::const_with_x`] is private
const ONE_COMMA_ZERO: = Cartesian.const_with_x;
Attribute args
The attribute can be further customized by the following space-separated positional args.
Builder Arg
An optional builder
positional arg controls whether to generate a builder struct that, at compile-time, ensures that every field is set exactly once before creating the struct.
use generic_array_struct;
expands to
use generic_array_struct;
// The const generic booleans track which fields have been set
;
pub type NewCartesianBuilder<Z> = ;
// impl notes:
// - cannot use transmute() due to generic, cannot move out of struct due to Drop.
// Hopefully rustc is able to optimize away all the
// transmute_copy() + core::mem::forget()s and use the same memory.
// I cannot wait for array transmutes to be stabilized.
/// This gets called if the Builder struct was dropped before `self.build()` was called
Example Builder Usages
Attempting to build before setting all fields
use generic_array_struct;
// y has not been set, this fails to compile with
// "method not found in `CartesianBuilder<{integer}, true, false>`"
let pt: = start.with_x.build;
Attempting to set a field twice
use generic_array_struct;
// attempted to set x twice, this fails to compile with
// "no method named `with_x` found for struct `CartesianBuilder<{integer}, true, true>` in the current scope"
let pt: = start.with_x.with_y.with_x.build;
Proper initialization
use generic_array_struct;
// proper initialization after setting all fields exactly once
let pt: = start.with_x.with_y.build;
.0
Visibility Attribute Arg
The attribute's second position arg is a syn::Visibility
that controls the visibility of the resulting .0
array field.
use generic_array_struct;
generates
;
while
use generic_array_struct;
generates
;
)