#![doc = include_str!("../README.md")]
pub trait FixedArray<Item>: Sized {
const N: usize;
fn as_slice(&self) -> &[Item];
fn from_fn<F: FnMut(usize) -> Item>(f: F) -> Self;
}
impl<Item, const N: usize> FixedArray<Item> for [Item; N] {
const N: usize = N;
#[inline]
fn as_slice(&self) -> &[Item] {
self
}
#[inline]
fn from_fn<F: FnMut(usize) -> Item>(f: F) -> Self {
::std::array::from_fn(f)
}
}
pub trait StructToArray<Item>: Sized {
type Arr: FixedArray<Item>;
fn to_arr(self) -> Self::Arr;
fn from_arr(arr: Self::Arr) -> Self;
#[inline]
fn num_fields() -> usize {
<Self::Arr as FixedArray<Item>>::N
}
}
pub trait StructToVec<Item>: Sized + StructToArray<Item>
where
Item: Clone,
{
fn to_vec(self) -> Vec<Item>;
fn from_vec(v: &[Item]) -> Self;
}
impl<S, Item> StructToVec<Item> for S
where
S: StructToArray<Item>,
Item: Clone,
{
#[inline]
fn to_vec(self) -> Vec<Item> {
let arr = self.to_arr();
arr.as_slice().to_vec()
}
#[inline]
fn from_vec(v: &[Item]) -> Self {
let expected = <S::Arr as FixedArray<Item>>::N;
assert!(
v.len() == expected,
"Input vec length {} does not match expected {}",
v.len(),
expected
);
let arr = <S::Arr as FixedArray<Item>>::from_fn(|i| v[i].clone());
Self::from_arr(arr)
}
}
pub use struct_to_array_derive::StructToArray;