use crate::vecmap::{self, Entry as VecMapEntry};
use core::hash::{BuildHasher, Hash};
use hashbrown::{
self,
hash_map::{self, Entry as HashBrownEntry},
};
use std::fmt;
pub enum Entry<'a, K, V, const N: usize, S> {
Occupied(OccupiedEntry<'a, K, V, N, S>),
Vacant(VacantEntry<'a, K, V, N, S>),
}
impl<'a, K, V, const N: usize, S> Entry<'a, K, V, N, S> {
#[inline]
pub fn or_insert(self, default: V) -> &'a mut V
where
K: Hash,
S: BuildHasher,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
#[inline]
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
where
K: Hash,
S: BuildHasher,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn key(&self) -> &K {
match *self {
Entry::Occupied(ref entry) => entry.key(),
Entry::Vacant(ref entry) => entry.key(),
}
}
#[inline]
#[must_use]
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
}
impl<'a, K, V: Default, const N: usize, S> Entry<'a, K, V, N, S> {
#[inline]
pub fn or_default(self) -> &'a mut V
where
K: Hash,
S: BuildHasher,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(Default::default()),
}
}
}
impl<'a, K, V, const N: usize, S> From<HashBrownEntry<'a, K, V, S>> for Entry<'a, K, V, N, S> {
fn from(f: HashBrownEntry<'a, K, V, S>) -> Entry<'a, K, V, N, S> {
match f {
HashBrownEntry::Occupied(o) => Entry::Occupied(OccupiedEntry(OccupiedEntryInt::Map(o))),
HashBrownEntry::Vacant(o) => Entry::Vacant(VacantEntry(VacantEntryInt::Map(o))),
}
}
}
impl<'a, K, V, const N: usize, S> From<VecMapEntry<'a, K, V, N, S>> for Entry<'a, K, V, N, S> {
fn from(f: VecMapEntry<'a, K, V, N, S>) -> Entry<'a, K, V, N, S> {
match f {
VecMapEntry::Occupied(o) => Entry::Occupied(OccupiedEntry(OccupiedEntryInt::Vec(o))),
VecMapEntry::Vacant(o) => Entry::Vacant(VacantEntry(VacantEntryInt::Vec(o))),
}
}
}
impl<K: fmt::Debug, V: fmt::Debug, const N: usize, S> fmt::Debug for Entry<'_, K, V, N, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
pub struct OccupiedEntry<'a, K, V, const N: usize, S>(OccupiedEntryInt<'a, K, V, S, N>);
enum OccupiedEntryInt<'a, K, V, S, const N: usize> {
Map(hash_map::OccupiedEntry<'a, K, V, S>),
Vec(vecmap::OccupiedEntry<'a, K, V, S, N>),
}
unsafe impl<K, V, const N: usize, S> Send for OccupiedEntry<'_, K, V, N, S>
where
K: Send,
V: Send,
S: Send,
{
}
unsafe impl<K, V, const N: usize, S> Sync for OccupiedEntry<'_, K, V, N, S>
where
K: Sync,
V: Sync,
S: Sync,
{
}
impl<K: fmt::Debug, V: fmt::Debug, const N: usize, S> fmt::Debug for OccupiedEntry<'_, K, V, N, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
OccupiedEntryInt::Map(m) => m.fmt(f),
OccupiedEntryInt::Vec(m) => m.fmt(f),
}
}
}
pub struct VacantEntry<'a, K, V, const N: usize, S>(VacantEntryInt<'a, K, V, N, S>);
enum VacantEntryInt<'a, K, V, const N: usize, S> {
Map(hashbrown::hash_map::VacantEntry<'a, K, V, S>),
Vec(vecmap::VacantEntry<'a, K, V, N, S>),
}
impl<K: fmt::Debug, V, const N: usize, S> fmt::Debug for VacantEntry<'_, K, V, N, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
VacantEntryInt::Map(m) => m.fmt(f),
VacantEntryInt::Vec(m) => m.fmt(f),
}
}
}
impl<'a, K, V, const N: usize, S> OccupiedEntry<'a, K, V, N, S> {
#[inline]
pub fn key(&self) -> &K {
match &self.0 {
OccupiedEntryInt::Map(m) => m.key(),
OccupiedEntryInt::Vec(m) => m.key(),
}
}
#[inline]
pub fn remove_entry(self) -> (K, V) {
match self.0 {
OccupiedEntryInt::Map(m) => m.remove_entry(),
OccupiedEntryInt::Vec(m) => m.remove_entry(),
}
}
#[inline]
pub fn get(&self) -> &V {
match &self.0 {
OccupiedEntryInt::Map(m) => m.get(),
OccupiedEntryInt::Vec(m) => m.get(),
}
}
#[inline]
pub fn get_mut(&mut self) -> &mut V {
match &mut self.0 {
OccupiedEntryInt::Map(m) => m.get_mut(),
OccupiedEntryInt::Vec(m) => m.get_mut(),
}
}
#[inline]
pub fn into_mut(self) -> &'a mut V {
match self.0 {
OccupiedEntryInt::Map(m) => m.into_mut(),
OccupiedEntryInt::Vec(m) => m.into_mut(),
}
}
#[inline]
pub fn insert(&mut self, value: V) -> V {
match &mut self.0 {
OccupiedEntryInt::Map(m) => m.insert(value),
OccupiedEntryInt::Vec(m) => m.insert(value),
}
}
#[inline]
pub fn remove(self) -> V {
match self.0 {
OccupiedEntryInt::Map(m) => m.remove(),
OccupiedEntryInt::Vec(m) => m.remove(),
}
}
#[inline]
pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, N, S>
where
F: FnOnce(&K, V) -> Option<V>,
V: Clone,
{
match self.0 {
OccupiedEntryInt::Map(m) => m.replace_entry_with(f).into(),
OccupiedEntryInt::Vec(m) => m.replace_entry_with(f).into(),
}
}
}
impl<'a, K, V, const N: usize, S> VacantEntry<'a, K, V, N, S> {
#[inline]
pub fn key(&self) -> &K {
match &self.0 {
VacantEntryInt::Map(m) => m.key(),
VacantEntryInt::Vec(m) => m.key(),
}
}
#[inline]
pub fn into_key(self) -> K {
match self.0 {
VacantEntryInt::Map(m) => m.into_key(),
VacantEntryInt::Vec(m) => m.into_key(),
}
}
#[inline]
pub fn insert(self, value: V) -> &'a mut V
where
K: Hash,
S: BuildHasher,
{
match self.0 {
VacantEntryInt::Map(m) => m.insert(value),
VacantEntryInt::Vec(m) => m.insert(value),
}
}
}