use num_traits::{PrimInt, Unsigned};
mod occupied;
mod vacant;
pub use occupied::*;
pub use vacant::*;
use crate::ConstLru;
#[derive(Debug)]
pub enum Entry<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> {
Occupied(OccupiedEntry<'a, K, V, CAP, I>),
Vacant(VacantEntry<'a, K, V, CAP, I>),
}
impl<'a, K: Ord, V, const CAP: usize, I: PrimInt + Unsigned> Entry<'a, K, V, CAP, I> {
pub(crate) fn new(const_lru: &'a mut ConstLru<K, V, CAP, I>, k: K) -> Self {
if CAP == 0 {
panic!("Entry API only works for CAP > 0");
}
let insert_bs_i = match const_lru.get_index_of(&k) {
Ok(tup) => return Self::Occupied(OccupiedEntry::new(const_lru, k, tup)),
Err(i) => i,
};
Self::Vacant(VacantEntry::new(const_lru, k, insert_bs_i))
}
}
impl<'a, K, V, const CAP: usize, I: PrimInt + Unsigned> Entry<'a, K, V, CAP, I> {
pub fn key(&self) -> &K {
match self {
Self::Occupied(e) => e.key(),
Self::Vacant(e) => e.key(),
}
}
}
impl<'a, K: Ord, V, const CAP: usize, I: PrimInt + Unsigned> Entry<'a, K, V, CAP, I> {
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Self::Occupied(e) => e.into_mut(),
Self::Vacant(e) => e.insert(default()).0,
}
}
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
match self {
Self::Occupied(e) => e.into_mut(),
Self::Vacant(e) => {
let v = default(e.key());
e.insert(v).0
}
}
}
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Self::Occupied(e) => e.into_mut(),
Self::Vacant(e) => e.insert(default).0,
}
}
}
impl<'a, K: Ord, V: Default, const CAP: usize, I: PrimInt + Unsigned> Entry<'a, K, V, CAP, I> {
pub fn or_default(self) -> &'a mut V {
self.or_insert(V::default())
}
}