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::generic_array_struct;
#[generic_array_struct]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct Cartesian<T> {
pub x: T,
pub y: T,
}
expands to
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct Cartesian<T>([T; CARTESIAN_LEN]);
impl<T> Cartesian<T> {
#[inline]
pub const fn x(&self) -> &T {
&self.0[CARTESIAN_IDX_X]
}
#[inline]
pub fn x_mut(&mut self) -> &mut T {
&mut self.0[CARTESIAN_IDX_X]
}
#[inline]
pub fn set_x(&mut self, val: T) -> T {
core::mem::replace(&mut self.0[CARTESIAN_IDX_X], val)
}
#[inline]
pub fn with_x(mut self, val: T) -> Self {
self.0[CARTESIAN_IDX_X] = val;
self
}
#[inline]
pub const fn y(&self) -> &T {
&self.0[CARTESIAN_IDX_Y]
}
#[inline]
pub fn y_mut(&mut self) -> &mut T {
&mut self.0[CARTESIAN_IDX_Y]
}
#[inline]
pub fn set_y(&mut self, val: T) -> T {
core::mem::replace(&mut self.0[CARTESIAN_IDX_Y], val)
}
#[inline]
pub fn with_y(mut self, val: T) -> Self {
self.0[CARTESIAN_IDX_Y] = val;
self
}
}
impl<T: Copy> Cartesian<T> {
#[inline]
pub const fn const_with_x(mut self, val: T) -> Self {
self.0[CARTESIAN_IDX_X] = val;
self
}
#[inline]
pub const fn const_with_y(mut self, val: T) -> Self {
self.0[CARTESIAN_IDX_Y] = val;
self
}
}
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::generic_array_struct;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[generic_array_struct]
pub struct Cartesian<D> {
pub x: D,
pub y: D,
}
RIGHT ✅
use generic_array_struct::generic_array_struct;
#[generic_array_struct]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Cartesian<D> {
pub x: D,
pub y: D,
}
Field Visibility
All methods have the same visibility as that of the originally declared field in the struct.
mod private {
use generic_array_struct::generic_array_struct;
#[generic_array_struct]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Cartesian<T> {
x: T,
y: T,
}
}
use private::Cartesian;
const ONE_COMMA_ZERO: Cartesian<f64> = Cartesian([0.0; 2]).const_with_x(1.0);
.0
Visibility Attribute Argument
The attribute accepts a single optional syn::Visibility
arg that controls the visibility of the resulting .0
array field.
use generic_array_struct::generic_array_struct;
#[generic_array_struct]
pub struct Cartesian<T> {
pub x: T,
pub y: T,
}
generates
pub struct Cartesian<T>([T; 2]);
while
use generic_array_struct::generic_array_struct;
#[generic_array_struct(pub(crate))]
pub struct Cartesian<T> {
pub x: T,
pub y: T,
}
generates
pub struct Cartesian<T>(pub(crate) [T; 2]);