use super::OrdMap;
#[derive(Debug)]
pub struct VacantEntry<'a, K, V, const N: usize> {
map: &'a mut OrdMap<K, V, N>,
key: K,
index: usize,
}
impl<'a, K, V, const N: usize> VacantEntry<'a, K, V, N> {
pub fn into_key(self) -> K {
self.key
}
pub fn key(&self) -> &K {
&self.key
}
pub fn index(&self) -> usize {
self.index
}
pub fn insert(self, value: V) -> Result<&'a mut V, (K, V)> {
self.map
.insert_at(self.index, self.key, value)
.map(|()| &mut self.map.values_mut_slice()[self.index])
}
}
#[derive(Debug)]
pub struct OccupiedEntry<'a, K, V, const N: usize> {
pub(super) map: &'a mut OrdMap<K, V, N>,
pub(super) index: usize,
}
impl<'a, K, V, const N: usize> OccupiedEntry<'a, K, V, N> {
pub fn key(&self) -> &K {
&self.map.keys_slice()[self.index]
}
pub fn get(&self) -> &V {
&self.map.values_slice()[self.index]
}
pub fn get_mut(&mut self) -> &mut V {
&mut self.map.values_mut_slice()[self.index]
}
pub fn into_mut(self) -> &'a mut V {
&mut self.map.values_mut_slice()[self.index]
}
pub fn index(&self) -> usize {
self.index
}
pub fn replace(&mut self, value: V) -> V {
core::mem::replace(&mut self.map.values_mut_slice()[self.index], value)
}
pub fn remove(self) -> V {
self.map.remove_at(self.index).1
}
pub fn remove_key_value(self) -> (K, V) {
self.map.remove_at(self.index)
}
}
#[derive(Debug)]
pub enum Entry<'a, K, V, const N: usize>
{
Vacant(VacantEntry<'a, K, V, N>),
Occupied(OccupiedEntry<'a, K, V, N>),
}
impl<'a, K, V, const N: usize> Entry<'a, K, V, N> {
pub(super) fn occupied(map: &'a mut OrdMap<K, V, N>, index: usize) -> Self {
Entry::Occupied(OccupiedEntry { map, index })
}
pub(super) fn vacant(map: &'a mut OrdMap<K, V, N>, index: usize, key: K) -> Self {
Entry::Vacant(VacantEntry { map, key, index })
}
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Entry::Vacant(entry) => Entry::Vacant(entry),
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
}
}
pub fn key(&self) -> &K {
match self {
Entry::Vacant(entry) => &entry.key,
Entry::Occupied(entry) => &entry.key(),
}
}
pub fn or_default(self) -> Result<&'a mut V, K>
where
V: Default,
{
self.or_insert_with(Default::default)
}
pub fn or_insert(self, value: V) -> Result<&'a mut V, (K, V)> {
match self {
Entry::Vacant(entry) => entry.insert(value),
Entry::Occupied(entry) => Ok(entry.into_mut()),
}
}
pub fn or_insert_with<F>(self, function: F) -> Result<&'a mut V, K>
where
F: FnOnce() -> V,
{
match self {
Entry::Vacant(entry) => {
if entry.map.len < N {
match entry.insert(function()) {
Ok(v) => Ok(v),
Err(_) => unreachable!(),
}
} else {
Err(entry.key)
}
}
Entry::Occupied(entry) => Ok(entry.into_mut()),
}
}
pub fn or_insert_with_key<F>(self, function: F) -> Result<&'a mut V, K>
where
F: FnOnce(&K) -> V,
{
match self {
Entry::Vacant(entry) => {
if entry.map.len < N {
let value = function(&entry.key);
match entry.insert(value) {
Ok(v) => Ok(v),
Err(_) => unreachable!(),
}
} else {
Err(entry.key)
}
}
Entry::Occupied(entry) => Ok(entry.into_mut()),
}
}
}