pub trait RawEntry<'a> {
type Key;
type Value;
private!();
fn key(&self) -> &Self::Key;
fn value(&self) -> Option<&Self::Value>;
fn value_mut(&mut self) -> Option<&mut Self::Value>;
}
pub trait Entry<'a>: RawEntry<'a> {
fn or_insert(self, value: Self::Value) -> &'a mut Self::Value;
fn or_insert_with<F>(self, f: F) -> &'a mut Self::Value
where
F: FnOnce() -> Self::Value;
}
#[cfg(feature = "alloc")]
macro_rules! entry {
($($prefix:ident)::* -> $call:ident($($arg:tt),*)) => {
$($prefix)::*::Entry::$call($($arg),*)
};
}
#[cfg(feature = "alloc")]
macro_rules! impl_entry {
(@raw $($prefix:ident)::* $(where $($preds:tt)*)?) => {
impl<'a, K, V> RawEntry<'a> for $($prefix)::*::Entry<'a, K, V> $(where $($preds)*)? {
type Key = K;
type Value = V;
seal!();
fn key(&self) -> &Self::Key {
entry!($($prefix)::* -> key(self))
}
fn value(&self) -> Option<&Self::Value> {
match self {
$($prefix)::*::Entry::Occupied(entry) => Some(entry.get()),
$($prefix)::*::Entry::Vacant(_) => None,
}
}
fn value_mut(&mut self) -> Option<&mut Self::Value> {
match self {
$($prefix)::*::Entry::Occupied(entry) => Some(entry.get_mut()),
$($prefix)::*::Entry::Vacant(_) => None,
}
}
}
};
(@entry $($prefix:ident)::* $(where $($preds:tt)*)?) => {
impl<'a, K, V> Entry<'a> for $($prefix)::*::Entry<'a, K, V> $(where $($preds)*)? {
fn or_insert(self, default: Self::Value) -> &'a mut Self::Value {
entry!($($prefix)::* -> or_insert(self, default))
}
fn or_insert_with<F>(self, f: F) -> &'a mut Self::Value
where
F: FnOnce() -> Self::Value,
{
entry!($($prefix)::* -> or_insert_with(self, f))
}
}
};
(@impl $($rest:tt)*) => {
impl_entry!(@raw $($rest)*);
impl_entry!(@entry $($rest)*);
};
($($rest:tt)*) => {
impl_entry!(@impl $($rest)*);
};
}
#[cfg(feature = "alloc")]
impl_entry! {
alloc::collections::btree_map where K: Ord
}
#[cfg(feature = "std")]
impl_entry! {
std::collections::hash_map where K: Eq + core::hash::Hash
}