use core::fmt::{Debug, Formatter, Result as FmtResult};
use alloc::vec::Vec;
use crate::key::Key;
pub trait Entries<T, TKey>: AsRef<[Entry<T, TKey>]> + AsMut<[Entry<T, TKey>]>
where
TKey: Key<T>,
{
fn capacity(&self) -> usize;
fn push(&mut self, entry: Entry<T, TKey>);
fn pop(&mut self) -> Option<Entry<T, TKey>>;
fn clear(&mut self);
fn shrink_to_fit(&mut self) {}
}
pub trait DynamicEntries<T, TKey>: Entries<T, TKey>
where
TKey: Key<T>,
{
fn with_capacity(capacity: usize) -> Self;
fn reserve(&mut self, additional: usize);
fn reserve_exact(&mut self, additional: usize);
}
impl<T, TKey> Entries<T, TKey> for Vec<Entry<T, TKey>>
where
TKey: Key<T>,
{
#[inline]
fn capacity(&self) -> usize {
Vec::capacity(self)
}
#[inline]
fn push(&mut self, entry: Entry<T, TKey>) {
Vec::push(self, entry);
}
#[inline]
fn pop(&mut self) -> Option<Entry<T, TKey>> {
Vec::pop(self)
}
#[inline]
fn clear(&mut self) {
Vec::clear(self);
}
#[inline]
fn shrink_to_fit(&mut self) {
Vec::shrink_to_fit(self);
}
}
impl<T, TKey> DynamicEntries<T, TKey> for Vec<Entry<T, TKey>>
where
TKey: Key<T>,
{
fn with_capacity(capacity: usize) -> Self {
Vec::with_capacity(capacity)
}
fn reserve(&mut self, additional: usize) {
Vec::reserve(self, additional);
}
fn reserve_exact(&mut self, additional: usize) {
Vec::reserve_exact(self, additional);
}
}
pub enum Entry<T, TKey>
where
TKey: Key<T>,
{
Vacant {
next: usize,
key_data: TKey::VacantData,
},
Occupied {
value: T,
key_data: TKey::OccupiedData,
#[cfg(feature = "range")]
range: RangeIndices,
},
Unknown,
}
impl<T, TKey> Clone for Entry<T, TKey>
where
T: Clone,
TKey: Key<T>,
TKey::VacantData: Clone,
TKey::OccupiedData: Clone,
{
fn clone(&self) -> Self {
match self {
Entry::Unknown => unreachable!(),
Entry::Vacant { next, key_data } => Entry::Vacant {
next: *next,
key_data: key_data.clone(),
},
Entry::Occupied {
value,
key_data,
#[cfg(feature = "range")]
range,
} => Entry::Occupied {
value: value.clone(),
key_data: key_data.clone(),
#[cfg(feature = "range")]
range: *range,
},
}
}
}
impl<T, TKey> Debug for Entry<T, TKey>
where
T: Debug,
TKey: Key<T>,
TKey::VacantData: Debug,
TKey::OccupiedData: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Entry::Unknown => write!(f, "Unknown"),
Entry::Vacant { next, key_data } => f
.debug_struct("Vacant")
.field("next", next)
.field("key_data", key_data)
.finish(),
Entry::Occupied {
value,
key_data,
#[cfg(feature = "range")]
range,
} => {
let mut s = f.debug_struct("Occupied");
s.field("value", value);
s.field("key_data", key_data);
#[cfg(feature = "range")]
s.field("range", range);
s.finish()
}
}
}
}
#[cfg(feature = "range")]
#[derive(Debug, Clone, Copy)]
pub struct RangeIndices {
pub(crate) prev: usize,
pub(crate) next: usize,
}