use core::ops::DerefMut;
use crate::index::{Index, Length, TreeIndex};
use crate::pointer::{Pointer, Width};
pub trait Storage<T>
where
Self: Sized + DerefMut<Target = [T]>,
{
type Error: 'static;
const EMPTY: Self;
fn with_capacity(capacity: usize) -> Result<Self, Self::Error>;
fn capacity(&self) -> usize;
fn push(&mut self, item: T) -> Result<(), Self::Error>;
}
#[cfg(feature = "alloc")]
impl<T> Storage<T> for alloc::vec::Vec<T> {
type Error = core::convert::Infallible;
const EMPTY: Self = alloc::vec::Vec::new();
#[inline]
fn with_capacity(capacity: usize) -> Result<Self, Self::Error> {
Ok(alloc::vec::Vec::with_capacity(capacity))
}
#[inline]
fn capacity(&self) -> usize {
alloc::vec::Vec::capacity(self)
}
#[inline]
fn push(&mut self, item: T) -> Result<(), Self::Error> {
alloc::vec::Vec::push(self, item);
Ok(())
}
}
#[macro_export]
macro_rules! flavor {
(
$(#[doc = $doc:literal])*
$vis:vis struct $ty:ident {
type Index = $index:ty;
$(type Width = $width:ty;)?
$(type Storage = $storage:ty;)?
$(type Indexes = $indexes:ty;)?
}
) => {
$(#[doc = $doc])*
#[non_exhaustive]
$vis struct $ty;
impl $crate::Flavor for $ty {
type Error = core::convert::Infallible;
type Index = $index;
type Length = <$index as $crate::Index>::Length;
type Width = $crate::flavor!(@width $($width)*);
type Pointer = $crate::flavor!(@pointer $($width)*);
type Storage<T> = $crate::macro_support::Vec<T>;
type Indexes = $crate::flavor!(@indexes $($indexes)*);
}
};
(@width $ty:ty) => { $ty };
(@width) => { usize };
(@pointer $ty:ty) => { <$ty as $crate::pointer::Width>::Pointer };
(@pointer) => { <usize as $crate::pointer::Width>::Pointer };
(@indexes $ty:ty) => { $ty };
(@indexes) => { $crate::macro_support::DefaultIndexes<Self> };
}
flavor! {
pub struct FlavorDefault {
type Index = u32;
type Width = usize;
}
}
pub trait Flavor {
type Error;
type Index: Index<Length = Self::Length>;
type Length: Length;
type Width: Width<Pointer = Self::Pointer>;
type Pointer: Pointer;
type Storage<T>: Storage<T, Error = Self::Error>;
type Indexes: Storage<TreeIndex<Self>, Error = Self::Error>;
}