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