use crate::{Equivalent, OrderMap};
use core::fmt;
use core::hash::{BuildHasher, Hash};
use indexmap::map::raw_entry_v1 as ix;
use indexmap::map::RawEntryApiV1 as _;
#[cfg(doc)]
use alloc::vec::Vec;
pub trait RawEntryApiV1<K, V, S>: private::Sealed {
fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S>;
fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S>;
}
impl<K, V, S> RawEntryApiV1<K, V, S> for OrderMap<K, V, S> {
fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S> {
RawEntryBuilder {
inner: self.inner.raw_entry_v1(),
}
}
fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
RawEntryBuilderMut {
inner: self.inner.raw_entry_mut_v1(),
}
}
}
pub struct RawEntryBuilder<'a, K, V, S> {
inner: ix::RawEntryBuilder<'a, K, V, S>,
}
impl<K, V, S> fmt::Debug for RawEntryBuilder<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S> {
pub fn from_key<Q>(self, key: &Q) -> Option<(&'a K, &'a V)>
where
S: BuildHasher,
Q: ?Sized + Hash + Equivalent<K>,
{
self.inner.from_key(key)
}
pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> Option<(&'a K, &'a V)>
where
Q: ?Sized + Equivalent<K>,
{
self.inner.from_key_hashed_nocheck(hash, key)
}
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
where
F: FnMut(&K) -> bool,
{
self.inner.from_hash(hash, is_match)
}
pub fn from_hash_full<F>(self, hash: u64, is_match: F) -> Option<(usize, &'a K, &'a V)>
where
F: FnMut(&K) -> bool,
{
self.inner.from_hash_full(hash, is_match)
}
pub fn index_from_hash<F>(self, hash: u64, is_match: F) -> Option<usize>
where
F: FnMut(&K) -> bool,
{
self.inner.index_from_hash(hash, is_match)
}
}
pub struct RawEntryBuilderMut<'a, K, V, S> {
inner: ix::RawEntryBuilderMut<'a, K, V, S>,
}
impl<K, V, S> fmt::Debug for RawEntryBuilderMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawEntryBuilderMut").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S> {
pub fn from_key<Q>(self, key: &Q) -> RawEntryMut<'a, K, V, S>
where
S: BuildHasher,
Q: ?Sized + Hash + Equivalent<K>,
{
RawEntryMut::new(self.inner.from_key(key))
}
pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> RawEntryMut<'a, K, V, S>
where
Q: ?Sized + Equivalent<K>,
{
RawEntryMut::new(self.inner.from_key_hashed_nocheck(hash, key))
}
pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
where
F: FnMut(&K) -> bool,
{
RawEntryMut::new(self.inner.from_hash(hash, is_match))
}
}
pub enum RawEntryMut<'a, K, V, S> {
Occupied(RawOccupiedEntryMut<'a, K, V, S>),
Vacant(RawVacantEntryMut<'a, K, V, S>),
}
impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut tuple = f.debug_tuple("RawEntryMut");
match self {
Self::Vacant(v) => tuple.field(v),
Self::Occupied(o) => tuple.field(o),
};
tuple.finish()
}
}
impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
fn new(entry: ix::RawEntryMut<'a, K, V, S>) -> Self {
match entry {
ix::RawEntryMut::Occupied(inner) => Self::Occupied(RawOccupiedEntryMut { inner }),
ix::RawEntryMut::Vacant(inner) => Self::Vacant(RawVacantEntryMut { inner }),
}
}
#[inline]
pub fn index(&self) -> usize {
match self {
Self::Occupied(entry) => entry.index(),
Self::Vacant(entry) => entry.index(),
}
}
pub fn or_insert(self, default_key: K, default_value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
match self {
Self::Occupied(entry) => entry.into_key_value_mut(),
Self::Vacant(entry) => entry.insert(default_key, default_value),
}
}
pub fn or_insert_with<F>(self, call: F) -> (&'a mut K, &'a mut V)
where
F: FnOnce() -> (K, V),
K: Hash,
S: BuildHasher,
{
match self {
Self::Occupied(entry) => entry.into_key_value_mut(),
Self::Vacant(entry) => {
let (key, value) = call();
entry.insert(key, value)
}
}
}
pub fn and_modify<F>(mut self, f: F) -> Self
where
F: FnOnce(&mut K, &mut V),
{
if let Self::Occupied(entry) = &mut self {
let (k, v) = entry.get_key_value_mut();
f(k, v);
}
self
}
}
pub struct RawOccupiedEntryMut<'a, K, V, S> {
inner: ix::RawOccupiedEntryMut<'a, K, V, S>,
}
impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawOccupiedEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawOccupiedEntryMut")
.field("key", self.key())
.field("value", self.get())
.finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
#[inline]
pub fn index(&self) -> usize {
self.inner.index()
}
pub fn key(&self) -> &K {
self.inner.key()
}
pub fn key_mut(&mut self) -> &mut K {
self.inner.key_mut()
}
pub fn into_key(self) -> &'a mut K {
self.inner.into_key()
}
pub fn get(&self) -> &V {
self.inner.get()
}
pub fn get_mut(&mut self) -> &mut V {
self.inner.get_mut()
}
pub fn into_mut(self) -> &'a mut V {
self.inner.into_mut()
}
pub fn get_key_value(&self) -> (&K, &V) {
self.inner.get_key_value()
}
pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
self.inner.get_key_value_mut()
}
pub fn into_key_value_mut(self) -> (&'a mut K, &'a mut V) {
self.inner.into_key_value_mut()
}
pub fn insert(&mut self, value: V) -> V {
self.inner.insert(value)
}
pub fn insert_key(&mut self, key: K) -> K {
self.inner.insert_key(key)
}
pub fn remove(self) -> V {
self.inner.shift_remove()
}
pub fn swap_remove(self) -> V {
self.inner.swap_remove()
}
pub fn remove_entry(self) -> (K, V) {
self.inner.shift_remove_entry()
}
pub fn swap_remove_entry(self) -> (K, V) {
self.inner.swap_remove_entry()
}
#[track_caller]
pub fn move_index(self, to: usize) {
self.inner.move_index(to);
}
#[track_caller]
pub fn swap_indices(self, other: usize) {
self.inner.swap_indices(other);
}
}
pub struct RawVacantEntryMut<'a, K, V, S> {
inner: ix::RawVacantEntryMut<'a, K, V, S>,
}
impl<K, V, S> fmt::Debug for RawVacantEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawVacantEntryMut").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
pub fn index(&self) -> usize {
self.inner.index()
}
pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
self.inner.insert(key, value)
}
pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
self.inner.insert_hashed_nocheck(hash, key, value)
}
#[track_caller]
pub fn shift_insert(self, index: usize, key: K, value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
self.inner.shift_insert(index, key, value)
}
#[track_caller]
pub fn shift_insert_hashed_nocheck(
self,
index: usize,
hash: u64,
key: K,
value: V,
) -> (&'a mut K, &'a mut V) {
self.inner
.shift_insert_hashed_nocheck(index, hash, key, value)
}
}
mod private {
pub trait Sealed {}
impl<K, V, S> Sealed for super::OrderMap<K, V, S> {}
}