struct_to_array/
lib.rs

1#![doc = include_str!("../README.md")]
2
3/// Convert between a homogeneous struct (all fields of type `Item`) and `[Item; N]`.
4///
5/// This is intentionally value-based (consumes `self` / takes array by value).
6/// That keeps it safe and requires no layout assumptions.
7pub trait StructToArray<Item, const N: usize>: Sized {
8    /// Number of atomic items of type `Item` in the struct (recursively).
9    const N_ATOMS: usize = N;
10    fn to_arr(self) -> [Item; N];
11    fn from_arr(a: [Item; N]) -> Self;
12    #[inline]
13    fn num_fields() -> usize {
14        assert!(
15            N == Self::N_ATOMS,
16            "Declared N ({}) does not match actual number of fields ({})",
17            N,
18            Self::N_ATOMS
19        );
20        N
21    }
22}
23
24pub trait StructToVec<Item, const N: usize>: Sized + StructToArray<Item, N>
25where
26    Item: Clone,
27{
28    fn to_vec(self) -> Vec<Item>;
29    fn from_vec(v: &[Item]) -> Self;
30}
31
32impl<S, Item, const N: usize> StructToVec<Item, N> for S
33where
34    S: StructToArray<Item, N>,
35    Item: Clone,
36{
37    #[inline]
38    fn to_vec(self) -> Vec<Item> {
39        let arr = self.to_arr();
40        arr.to_vec()
41    }
42    #[inline]
43    fn from_vec(v: &[Item]) -> Self {
44        assert!(
45            v.len() == N,
46            "Input vec length {} does not match expected {}",
47            v.len(),
48            N
49        );
50        let arr: [Item; N] = std::array::from_fn(|i| v[i].clone());
51        Self::from_arr(arr)
52    }
53}
54
55pub use struct_to_array_derive::StructToArray;