#[cfg(feature = "alloc")]
use alloc::{vec, vec::Vec};
use core::array;
use crate::sealed::Sealed;
pub trait BufferFactory {
#[doc(hidden)]
#[expect(private_bounds)]
type Buffer<T>: Buffer<T>
where
T: Default;
#[doc(hidden)]
#[expect(private_interfaces)]
fn new<T>(_: Sealed) -> Self::Buffer<T>
where
T: Default;
}
pub struct StackFactory<const LEN: usize>;
impl<const LEN: usize> BufferFactory for StackFactory<LEN> {
type Buffer<T>
= Stack<LEN, T>
where
T: Default;
#[expect(private_interfaces)]
fn new<T>(_: Sealed) -> Self::Buffer<T>
where
T: Default,
{
Stack {
length: 1,
stack: array::from_fn::<_, LEN, _>(|_| T::default()),
}
}
}
#[cfg(feature = "alloc")]
pub struct HeapFactory;
#[cfg(feature = "alloc")]
impl BufferFactory for HeapFactory {
type Buffer<T>
= Heap<T>
where
T: Default;
#[expect(private_interfaces)]
fn new<T>(_: Sealed) -> Self::Buffer<T>
where
T: Default,
{
Heap {
stack: vec![T::default()],
}
}
}
pub(crate) trait Buffer<T> {
fn push(&mut self, _: Sealed);
fn pop(&mut self, _: Sealed);
fn last_mut(&mut self, _: Sealed) -> Option<&mut T>;
fn get_mut(&mut self, x: usize, _: Sealed) -> Option<&mut T>;
fn depth(&self, _: Sealed) -> usize;
fn max_depth(&self, _: Sealed) -> usize;
}
#[doc(hidden)]
pub struct Stack<const LEN: usize, T> {
length: usize,
stack: [T; LEN],
}
impl<const LEN: usize, T> Buffer<T> for Stack<LEN, T>
where
T: Default,
{
fn push(&mut self, _: Sealed) {
self.length = self.length.saturating_add(1);
if let Some(y) = self.stack.get_mut(self.length) {
*y = T::default();
}
}
fn pop(&mut self, _: Sealed) {
self.length = self.length.saturating_sub(1);
}
fn get_mut(&mut self, x: usize, _: Sealed) -> Option<&mut T> {
self.stack.get_mut(x)
}
fn last_mut(&mut self, _: Sealed) -> Option<&mut T> {
let depth = self.depth(Sealed);
self.stack.get_mut(depth)
}
fn depth(&self, _: Sealed) -> usize {
self.length.saturating_sub(1)
}
fn max_depth(&self, _: Sealed) -> usize {
LEN
}
}
#[doc(hidden)]
#[cfg(feature = "alloc")]
pub struct Heap<T> {
stack: Vec<T>,
}
#[cfg(feature = "alloc")]
impl<T> Buffer<T> for Heap<T>
where
T: Default,
{
fn push(&mut self, _: Sealed) {
self.stack.push(T::default());
}
fn pop(&mut self, _: Sealed) {
self.stack.pop();
}
fn get_mut(&mut self, x: usize, _: Sealed) -> Option<&mut T> {
self.stack.get_mut(x)
}
fn last_mut(&mut self, _: Sealed) -> Option<&mut T> {
self.stack.last_mut()
}
fn depth(&self, _: Sealed) -> usize {
self.stack.len().saturating_sub(1)
}
fn max_depth(&self, _: Sealed) -> usize {
unreachable!()
}
}