use crate::FromNonEmptyIterator;
use crate::IntoNonEmptyIterator;
use crate::NonEmptyIterator;
use crate::Singleton;
use indexmap::indexmap;
use indexmap::Equivalent;
use indexmap::IndexMap;
use std::fmt;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::hash::BuildHasher;
use std::hash::Hash;
use std::num::NonZeroUsize;
#[macro_export]
macro_rules! ne_indexmap {
($hk:expr => $hv:expr, $( $xk:expr => $xv:expr,)+) => { $crate::ne_indexmap!{$hk => $hv, $($xk => $xv),+} };
($hk:expr => $hv:expr, $( $xk:expr => $xv:expr ),*) => {{
const CAP: core::num::NonZeroUsize = core::num::NonZeroUsize::MIN.saturating_add(<[()]>::len(&[$({ stringify!($xk); }),*]));
let mut map = $crate::index_map::NEIndexMap::with_capacity(CAP, $hk, $hv);
$( map.insert($xk, $xv); )*
map
}};
($hk:expr => $hv:expr) => {
$crate::index_map::NEIndexMap::new($hk, $hv)
}
}
#[derive(Clone)]
pub struct NEIndexMap<K, V, S = std::collections::hash_map::RandomState> {
inner: IndexMap<K, V, S>,
}
impl<K, V, S> NEIndexMap<K, V, S> {
#[must_use]
pub fn capacity(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) }
}
#[must_use]
pub fn hasher(&self) -> &S {
self.inner.hasher()
}
pub fn iter(&self) -> indexmap::map::Iter<'_, K, V> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> indexmap::map::IterMut<'_, K, V> {
self.inner.iter_mut()
}
pub fn nonempty_iter(&self) -> Iter<'_, K, V> {
Iter {
iter: self.inner.iter(),
}
}
pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
iter: self.inner.iter_mut(),
}
}
pub fn keys(&self) -> Keys<'_, K, V> {
Keys {
inner: self.inner.keys(),
}
}
#[must_use]
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
#[deprecated(note = "A NEIndexMap is never empty.")]
#[must_use]
pub const fn is_empty(&self) -> bool {
false
}
pub fn values(&self) -> Values<'_, K, V> {
Values {
inner: self.inner.values(),
}
}
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut {
inner: self.inner.values_mut(),
}
}
#[allow(clippy::missing_panics_doc)] #[must_use]
pub fn first(&self) -> (&K, &V) {
self.inner.first().unwrap()
}
#[allow(clippy::missing_panics_doc)] #[must_use]
pub fn last(&self) -> (&K, &V) {
self.inner.last().unwrap()
}
}
impl<K: Debug, V: Debug, S> Debug for NEIndexMap<K, V, S> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.nonempty_iter()).finish()
}
}
impl<K, V> NEIndexMap<K, V>
where
K: Eq + Hash,
{
#[must_use]
pub fn new(k: K, v: V) -> Self {
Self {
inner: indexmap! {k => v},
}
}
#[must_use]
pub fn with_capacity(capacity: NonZeroUsize, k: K, v: V) -> NEIndexMap<K, V> {
let mut inner = IndexMap::with_capacity(capacity.get());
inner.insert(k, v);
Self { inner }
}
}
impl<K, V, S> NEIndexMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
#[must_use]
pub fn try_from_map(map: IndexMap<K, V, S>) -> Option<Self> {
if map.is_empty() {
None
} else {
Some(Self { inner: map })
}
}
#[must_use]
pub fn contains_key<Q>(&self, k: &Q) -> bool
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.inner.contains_key(k)
}
#[must_use]
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.inner.get(k)
}
#[must_use]
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.inner.get_key_value(key)
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.inner.get_mut(key)
}
#[must_use]
pub fn get_index_of<Q>(&self, key: &Q) -> Option<usize>
where
Q: Hash + Equivalent<K> + ?Sized,
{
self.inner.get_index_of(key)
}
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
self.inner.insert(k, v)
}
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit();
}
#[must_use]
pub fn with_capacity_and_hasher(
capacity: NonZeroUsize,
hasher: S,
k: K,
v: V,
) -> NEIndexMap<K, V, S> {
let mut inner = IndexMap::with_capacity_and_hasher(capacity.get(), hasher);
inner.insert(k, v);
Self { inner }
}
#[must_use]
pub fn with_hasher(hasher: S, k: K, v: V) -> NEIndexMap<K, V, S> {
let mut inner = IndexMap::with_hasher(hasher);
inner.insert(k, v);
Self { inner }
}
pub fn swap_indices(&mut self, a: usize, b: usize) {
self.inner.swap_indices(a, b);
}
}
impl<K, V, S> AsRef<IndexMap<K, V, S>> for NEIndexMap<K, V, S> {
fn as_ref(&self) -> &IndexMap<K, V, S> {
&self.inner
}
}
impl<K, V, S> AsMut<IndexMap<K, V, S>> for NEIndexMap<K, V, S> {
fn as_mut(&mut self) -> &mut IndexMap<K, V, S> {
&mut self.inner
}
}
impl<K, V, S> PartialEq for NEIndexMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
fn eq(&self, other: &Self) -> bool {
self.inner.eq(&other.inner)
}
}
impl<K, V, S> Eq for NEIndexMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}
impl<K, V, S> From<NEIndexMap<K, V, S>> for IndexMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn from(m: NEIndexMap<K, V, S>) -> Self {
m.inner
}
}
impl<K, V, S> IntoNonEmptyIterator for NEIndexMap<K, V, S> {
type IntoNEIter = IntoIter<K, V>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
IntoIter {
iter: self.inner.into_iter(),
}
}
}
impl<'a, K, V, S> IntoNonEmptyIterator for &'a NEIndexMap<K, V, S> {
type IntoNEIter = Iter<'a, K, V>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
self.nonempty_iter()
}
}
impl<K, V, S> IntoIterator for NEIndexMap<K, V, S> {
type Item = (K, V);
type IntoIter = indexmap::map::IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a NEIndexMap<K, V, S> {
type Item = (&'a K, &'a V);
type IntoIter = indexmap::map::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut NEIndexMap<K, V, S> {
type Item = (&'a K, &'a mut V);
type IntoIter = indexmap::map::IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K, V, S> FromNonEmptyIterator<(K, V)> for NEIndexMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = (K, V)>,
{
Self {
inner: iter.into_nonempty_iter().into_iter().collect(),
}
}
}
impl<K, V> std::ops::Index<usize> for NEIndexMap<K, V> {
type Output = V;
fn index(&self, index: usize) -> &V {
self.inner.index(index)
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, K: 'a, V: 'a> {
iter: indexmap::map::Iter<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Iter<'_, K, V> {}
impl<'a, K, V> IntoIterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
type IntoIter = indexmap::map::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K, V> Clone for Iter<'_, K, V> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<K: Debug, V: Debug> Debug for Iter<'_, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct IterMut<'a, K: 'a, V: 'a> {
iter: indexmap::map::IterMut<'a, K, V>,
}
impl<K, V> NonEmptyIterator for IterMut<'_, K, V> {}
impl<'a, K, V> IntoIterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
type IntoIter = indexmap::map::IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K: Debug, V: Debug> Debug for IterMut<'_, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
pub struct IntoIter<K, V> {
iter: indexmap::map::IntoIter<K, V>,
}
impl<K, V> NonEmptyIterator for IntoIter<K, V> {}
impl<K, V> IntoIterator for IntoIter<K, V> {
type Item = (K, V);
type IntoIter = indexmap::map::IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K: Debug, V: Debug> Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Keys<'a, K: 'a, V: 'a> {
inner: indexmap::map::Keys<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Keys<'_, K, V> {}
impl<'a, K, V> IntoIterator for Keys<'a, K, V> {
type Item = &'a K;
type IntoIter = indexmap::map::Keys<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<K, V> Clone for Keys<'_, K, V> {
fn clone(&self) -> Self {
Keys {
inner: self.inner.clone(),
}
}
}
impl<K: Debug, V: Debug> Debug for Keys<'_, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Values<'a, K: 'a, V: 'a> {
inner: indexmap::map::Values<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Values<'_, K, V> {}
impl<'a, K, V> IntoIterator for Values<'a, K, V> {
type Item = &'a V;
type IntoIter = indexmap::map::Values<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<K, V> Clone for Values<'_, K, V> {
fn clone(&self) -> Self {
Values {
inner: self.inner.clone(),
}
}
}
impl<K: Debug, V: Debug> Debug for Values<'_, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct ValuesMut<'a, K: 'a, V: 'a> {
inner: indexmap::map::ValuesMut<'a, K, V>,
}
impl<K, V> NonEmptyIterator for ValuesMut<'_, K, V> {}
impl<'a, K, V> IntoIterator for ValuesMut<'a, K, V> {
type Item = &'a mut V;
type IntoIter = indexmap::map::ValuesMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<K: Debug, V: Debug> Debug for ValuesMut<'_, K, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<K, V> Singleton for NEIndexMap<K, V>
where
K: Eq + Hash,
{
type Item = (K, V);
fn singleton((k, v): Self::Item) -> Self {
NEIndexMap::new(k, v)
}
}
impl<K, V> Extend<(K, V)> for NEIndexMap<K, V>
where
K: Eq + Hash,
{
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
self.inner.extend(iter);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_swap_indices() {
let mut map = ne_indexmap! { 0 => (), 1 => () };
assert_eq!(vec![0, 1], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(0, 1);
assert_eq!(vec![1, 0], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(1, 0);
assert_eq!(vec![0, 1], map.keys().copied().collect::<Vec<_>>());
let mut map = ne_indexmap! { 0 => (), 1 => (), 2 => () };
assert_eq!(vec![0, 1, 2], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(0, 1);
assert_eq!(vec![1, 0, 2], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(1, 0);
assert_eq!(vec![0, 1, 2], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(0, 2);
assert_eq!(vec![2, 1, 0], map.keys().copied().collect::<Vec<_>>());
map.swap_indices(1, 2);
assert_eq!(vec![2, 0, 1], map.keys().copied().collect::<Vec<_>>());
let mut map = ne_indexmap! { 0 => (), 1 => (), 2 => (), 3 => (), 4 => (), 5 => () };
assert_eq!(
vec![0, 1, 2, 3, 4, 5],
map.keys().copied().collect::<Vec<_>>()
);
map.swap_indices(1, 2);
assert_eq!(
vec![0, 2, 1, 3, 4, 5],
map.keys().copied().collect::<Vec<_>>()
);
map.swap_indices(0, 3);
assert_eq!(
vec![3, 2, 1, 0, 4, 5],
map.keys().copied().collect::<Vec<_>>()
);
}
#[test]
fn debug_impl() {
let expected = format!("{:?}", indexmap! {0 => 10, 1 => 11, 2 => 12});
let actual = format!("{:?}", ne_indexmap! {0 => 10, 1 => 11, 2 => 12});
assert_eq!(expected, actual);
}
#[test]
fn iter_mut() {
let mut v = ne_indexmap! {"a" => 0, "b" => 1, "c" => 2};
v.iter_mut().for_each(|(_k, v)| {
*v += 1;
});
assert_eq!(ne_indexmap! {"a" => 1, "b" => 2, "c" => 3}, v);
for (_k, v) in &mut v {
*v -= 1;
}
assert_eq!(ne_indexmap! {"a" => 0, "b" => 1, "c" => 2}, v);
}
}