use crate::{Safe, SafetyMarker, Unsafe};
#[cfg(feature = "std")]
use std::{
collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque},
hash::Hash,
};
pub trait Remove<K, V> {
type Safety: SafetyMarker;
fn remove(&mut self, k: K) -> Option<V>;
}
impl<'r, K, V, R: Remove<K, V>> Remove<K, V> for &'r mut R {
type Safety = <R as Remove<K, V>>::Safety;
fn remove<'a>(&'a mut self, k: K) -> Option<V> {
<R as Remove<K, V>>::remove(self, k)
}
}
impl<V> Remove<usize, V> for Vec<V> {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<V> {
Some(self.remove(k))
}
}
#[cfg(feature = "std")]
impl<V> Remove<usize, V> for VecDeque<V> {
type Safety = Safe;
fn remove(&mut self, k: usize) -> Option<V> {
VecDeque::remove(self, k)
}
}
#[cfg(feature = "std")]
impl<V> Remove<usize, V> for LinkedList<V> {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<V> {
let mut rest = self.split_off(k);
let v = self.pop_front();
self.append(&mut rest);
v
}
}
#[cfg(feature = "std")]
impl<'k, K: Ord, V> Remove<&'k K, V> for BTreeMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<V> {
self.remove(k)
}
}
#[cfg(feature = "std")]
impl<K: Ord, V> Remove<K, V> for BTreeMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<V> {
self.remove(&k)
}
}
#[cfg(feature = "std")]
impl<'k, K: Ord> Remove<&'k K, ()> for BTreeSet<K> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<()> {
if self.remove(k) {
Some(())
} else {
None
}
}
}
#[cfg(feature = "std")]
impl<K: Ord> Remove<K, ()> for BTreeSet<K> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<()> {
if self.remove(&k) {
Some(())
} else {
None
}
}
}
#[cfg(feature = "std")]
impl<'k, K: Eq + Hash, V> Remove<&'k K, V> for HashMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<V> {
self.remove(k)
}
}
#[cfg(feature = "std")]
impl<K: Eq + Hash, V> Remove<K, V> for HashMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<V> {
self.remove(&k)
}
}
#[cfg(feature = "std")]
impl<'k, K: Eq + Hash> Remove<&'k K, ()> for HashSet<K> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<()> {
if self.remove(k) {
Some(())
} else {
None
}
}
}
#[cfg(feature = "std")]
impl<K: Eq + Hash> Remove<K, ()> for HashSet<K> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<()> {
if self.remove(&k) {
Some(())
} else {
None
}
}
}
#[cfg(feature = "dashmap")]
use dashmap::{DashMap, DashSet};
#[cfg(feature = "dashmap")]
impl<'k, K: Eq + Hash, V> Remove<&'k K, V> for DashMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<V> {
DashMap::remove(self, k).map(|v| v.1)
}
}
#[cfg(feature = "dashmap")]
impl<K: Eq + Hash, V> Remove<K, V> for DashMap<K, V> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<V> {
DashMap::remove(self, &k).map(|v| v.1)
}
}
#[cfg(feature = "dashmap")]
impl<'k, K: Eq + Hash> Remove<&'k K, K> for DashSet<K> {
type Safety = Safe;
fn remove(&mut self, k: &'k K) -> Option<K> {
DashSet::remove(self, k)
}
}
#[cfg(feature = "dashmap")]
impl<K: Eq + Hash> Remove<K, K> for DashSet<K> {
type Safety = Safe;
fn remove(&mut self, k: K) -> Option<K> {
DashSet::remove(self, &k)
}
}
#[cfg(feature = "serde_json")]
use serde_json::Value as SeV;
#[cfg(feature = "serde_json")]
impl<'k> Remove<&'k str, SeV> for SeV {
type Safety = Unsafe;
fn remove(&mut self, k: &'k str) -> Option<SeV> {
match self {
SeV::Object(o) => o.remove(k),
_ => panic!("Value is not an object"),
}
}
}
#[cfg(feature = "serde_json")]
impl Remove<usize, SeV> for SeV {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<SeV> {
match self {
SeV::Array(a) => Some(a.remove(k)),
_ => panic!("Value is not an array"),
}
}
}
#[cfg(feature = "simd-json")]
use simd_json::{BorrowedValue as SBV, OwnedValue as SOV};
#[cfg(feature = "simd-json")]
impl<'k, 'a> Remove<&'k str, SBV<'a>> for SBV<'a> {
type Safety = Unsafe;
fn remove(&mut self, k: &'k str) -> Option<SBV<'a>> {
match self {
SBV::Object(o) => o.remove(k),
_ => panic!("Value is not an object"),
}
}
}
#[cfg(feature = "simd-json")]
impl<'a> Remove<usize, SBV<'a>> for SBV<'a> {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<SBV<'a>> {
match self {
SBV::Array(a) => Some(a.remove(k)),
_ => panic!("Value is not an array"),
}
}
}
#[cfg(feature = "simd-json")]
impl<'k> Remove<&'k str, SOV> for SOV {
type Safety = Unsafe;
fn remove(&mut self, k: &'k str) -> Option<SOV> {
match self {
SOV::Object(o) => o.remove(k),
_ => panic!("Value is not an object"),
}
}
}
#[cfg(feature = "simd-json")]
impl Remove<usize, SOV> for SOV {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<SOV> {
match self {
SOV::Array(a) => Some(a.remove(k)),
_ => panic!("Value is not an array"),
}
}
}
#[cfg(feature = "slab")]
use slab::Slab;
#[cfg(feature = "slab")]
impl<V> Remove<usize, V> for Slab<V> {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<V> {
Some(self.remove(k))
}
}
#[cfg(feature = "smallvec")]
use smallvec::{Array, SmallVec};
#[cfg(feature = "smallvec")]
impl<V, A: Array<Item = V>> Remove<usize, V> for SmallVec<A> {
type Safety = Unsafe;
fn remove(&mut self, k: usize) -> Option<V> {
Some(self.remove(k))
}
}