use gc::{custom_trace, Finalize, Trace};
use indexmap::{map::IntoIter, map::Iter, map::IterMut, IndexMap};
use std::collections::hash_map::RandomState;
use std::fmt::Debug;
use std::hash::{BuildHasher, Hash};
#[derive(Clone)]
pub struct OrderedMap<K, V, S = RandomState>(IndexMap<K, V, S>)
where
K: Hash + Eq;
impl<K: Eq + Hash + Trace, V: Trace, S: BuildHasher> Finalize for OrderedMap<K, V, S> {}
unsafe impl<K: Eq + Hash + Trace, V: Trace, S: BuildHasher> Trace for OrderedMap<K, V, S> {
custom_trace!(this, {
for (k, v) in this.0.iter() {
mark(k);
mark(v);
}
});
}
impl<K: Hash + Eq + Debug, V: Debug> Debug for OrderedMap<K, V> {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.0.fmt(formatter)
}
}
impl<K: Hash + Eq, V> Default for OrderedMap<K, V> {
fn default() -> Self {
Self::new()
}
}
impl<K, V> OrderedMap<K, V>
where
K: Hash + Eq,
{
pub fn new() -> Self {
OrderedMap(IndexMap::new())
}
pub fn with_capacity(capacity: usize) -> Self {
OrderedMap(IndexMap::with_capacity(capacity))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.len() == 0
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.0.insert(key, value)
}
pub fn remove(&mut self, key: &K) -> Option<V> {
self.0.shift_remove(key)
}
pub fn get(&self, key: &K) -> Option<&V> {
self.0.get(key)
}
pub fn iter(&self) -> Iter<'_, K, V> {
self.0.iter()
}
pub fn contains_key(&self, key: &K) -> bool {
self.0.contains_key(key)
}
}
impl<'a, K, V, S> IntoIterator for &'a OrderedMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut OrderedMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<K, V, S> IntoIterator for OrderedMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher,
{
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
self.0.into_iter()
}
}