use get::GetMut;
pub trait GetEntry<'a>: GetMut {
type Occupied: OccupiedEntry<'a, Self>;
type Vacant: VacantEntry<'a, Self>;
fn entry(&'a mut self, key: Self::Key) -> Entry<'a, Self>;
}
pub enum Entry<'a, T: ?Sized + GetEntry<'a>> {
Occupied(T::Occupied),
Vacant(T::Vacant),
}
impl<'a, T: ?Sized + GetEntry<'a>> Entry<'a, T> {
pub fn or_insert(self, default: T::Value) -> &'a mut T::Value {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
pub fn or_insert_with<F: FnOnce() -> T::Value>(self, default: F) -> &'a mut T::Value {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
}
pub trait OccupiedEntry<'a, T: ?Sized + GetEntry<'a>> {
fn key(&self) -> &T::Key;
fn get(&self) -> &T::Value;
fn get_mut(&mut self) -> &mut T::Value;
fn insert(&mut self, value: T::Value) -> T::Value;
fn into_mut(self) -> &'a mut T::Value;
fn remove_entry(self) -> (T::Key, T::Value);
}
pub trait VacantEntry<'a, T: ?Sized + GetEntry<'a>> {
fn key(&self) -> &T::Key;
fn into_key(self) -> T::Key;
fn insert(self, value: T::Value) -> &'a mut T::Value;
}