use std::mem::MaybeUninit;
pub mod state;
pub mod sealed {
pub trait Sealed {}
}
#[derive(Debug)]
pub struct PushableArray<const N: usize, T> {
len: usize,
array: [MaybeUninit<T>; N],
}
impl<const N: usize, T> Default for PushableArray<N, T> {
fn default() -> Self {
Self::new()
}
}
impl<const N: usize, T> PushableArray<N, T> {
pub const fn new() -> Self {
Self {
array: [const { MaybeUninit::uninit() }; N],
len: 0,
}
}
pub fn push(&mut self, t: T) {
if self.len < N {
self.array[self.len].write(t);
}
self.len += 1;
}
pub const fn len(&self) -> usize {
self.len
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn is_valid(&self) -> bool {
self.len == N
}
pub const fn has_too_many(&self) -> bool {
self.len > N
}
pub const fn into_array(self) -> Option<[T; N]> {
if self.is_valid() {
const {
assert!(
std::mem::size_of::<[T; N]>() == std::mem::size_of::<[MaybeUninit<T>; N]>()
);
}
let array = unsafe { std::mem::transmute_copy(&self.array) };
Some(array)
} else {
None
}
}
}
#[cfg(test)]
mod test {
use crate::__private::PushableArray;
#[test]
fn pushable_array() {
let mut a = PushableArray::<2, u32>::new();
a.push(69);
a.push(420);
assert!(a.is_valid());
assert!(!a.has_too_many());
let a = a.into_array().unwrap();
assert_eq!(a, [69, 420]);
}
#[test]
fn pushable_array_too_many() {
let mut a = PushableArray::<2, u32>::new();
a.push(69);
a.push(420);
a.push(1337);
assert!(!a.is_valid());
assert!(a.has_too_many());
assert_eq!(a.into_array(), None);
}
#[test]
fn pushable_array_too_few() {
let mut a = PushableArray::<2, u32>::new();
a.push(69);
assert!(!a.is_valid());
assert!(!a.has_too_many());
assert_eq!(a.into_array(), None);
}
}