#![allow(
// `_manage_hash` is also used by BTreeMap
clippy::map_entry
)]
macro_rules! _manage_hash {
($hash:expr, $key:expr, $value:expr) => {{
if $hash.contains_key(&$key) {
Err(crate::Error::AlreadyExistingElement)
} else {
let _maybe_discarded = $hash.insert($key, $value);
Ok(())
}
}};
}
macro_rules! _manage_set {
($set:expr, $value:expr) => {{
if $set.contains(&$value) {
Err(crate::Error::AlreadyExistingElement)
} else {
let _ = $set.insert($value);
Ok(())
}
}};
}
#[cfg(feature = "alloc")]
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet};
pub trait Insert {
type Error;
type Input;
fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error>;
}
impl<T> Insert for &mut T
where
T: Insert,
{
type Error = T::Error;
type Input = T::Input;
#[inline]
fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> {
(*self).insert(input)
}
}
#[cfg(feature = "alloc")]
impl<K, V> Insert for BTreeMap<K, V>
where
K: Ord,
{
type Error = crate::Error;
type Input = (K, V);
#[inline]
fn insert(&mut self, (key, val): Self::Input) -> Result<(), Self::Error> {
_manage_hash!(self, key, val)
}
}
#[cfg(feature = "alloc")]
impl<V> Insert for BTreeSet<V>
where
V: Ord,
{
type Error = crate::Error;
type Input = V;
#[inline]
fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> {
_manage_set!(self, input)
}
}
#[cfg(feature = "std")]
impl<K, V, S> Insert for HashMap<K, V, S>
where
K: Eq + core::hash::Hash,
S: core::hash::BuildHasher,
{
type Error = crate::Error;
type Input = (K, V);
#[inline]
fn insert(&mut self, (k, v): Self::Input) -> Result<(), Self::Error> {
_manage_hash!(self, k, v)
}
}
#[cfg(feature = "std")]
impl<V, S> Insert for HashSet<V, S>
where
V: core::hash::Hash + Eq,
S: core::hash::BuildHasher,
{
type Error = crate::Error;
type Input = V;
#[inline]
fn insert(&mut self, v: Self::Input) -> Result<(), Self::Error> {
_manage_set!(self, v)
}
}
impl<T> Insert for Option<T> {
type Error = crate::Error;
type Input = T;
#[inline]
fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> {
if self.is_some() {
Err(crate::Error::InsufficientCapacity(1))
} else {
*self = Some(input);
Ok(())
}
}
}
#[cfg(feature = "alloc")]
impl<T> Insert for Vec<T> {
type Error = crate::Error;
type Input = (usize, T);
#[inline]
fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> {
_check_indcs!(self, idx);
self.insert(idx, elem);
Ok(())
}
}
#[cfg(feature = "arrayvec")]
impl<T, const N: usize> Insert for arrayvec::ArrayVec<T, N> {
type Error = crate::Error;
type Input = (usize, T);
#[inline]
fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> {
_check_indcs!(self, idx);
self.insert(idx, elem);
Ok(())
}
}
#[cfg(feature = "smallvec")]
impl<A> Insert for smallvec::SmallVec<A>
where
A: smallvec::Array,
{
type Error = crate::Error;
type Input = (usize, A::Item);
#[inline]
fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> {
_check_indcs!(self, idx);
self.insert(idx, elem);
Ok(())
}
}
#[cfg(feature = "tinyvec")]
impl<A> Insert for tinyvec::ArrayVec<A>
where
A: tinyvec::Array,
A::Item: Default,
{
type Error = crate::Error;
type Input = (usize, A::Item);
#[inline]
fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> {
_check_indcs!(self, idx);
self.insert(idx, elem);
Ok(())
}
}
#[cfg(all(feature = "alloc", feature = "tinyvec"))]
impl<A> Insert for tinyvec::TinyVec<A>
where
A: tinyvec::Array,
A::Item: Default,
{
type Error = crate::Error;
type Input = (usize, A::Item);
#[inline]
fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> {
_check_indcs!(self, idx);
self.insert(idx, elem);
Ok(())
}
}