use std::fmt::Debug;
use crate::small::stack_vec::{StackVec, StackVecIntoIter};
#[derive(Clone)]
pub struct StackMap<K: Eq, V>(pub(super) StackVec<(K, V)>);
impl<K: Eq, V> StackMap<K, V> {
pub fn new() -> Self {
StackMap(StackVec::new())
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
match self.0.as_slice().iter().position(|(a, _)| *a == k) {
Some(pos) => {
let mut output = v;
std::mem::swap(&mut self.0[pos].1, &mut output);
Some(output)
}
None => {
self.0.push((k, v));
None
}
}
}
pub fn get(&self, k: &K) -> Option<&V> {
self.0
.as_slice()
.iter()
.find_map(|(a, v)| if a == k { Some(v) } else { None })
}
pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
self.0
.as_mut_slice()
.iter_mut()
.find_map(|(a, v)| if a == k { Some(v) } else { None })
}
pub fn remove(&mut self, k: &K) -> Option<V> {
match self.0.as_slice().iter().position(|(a, _)| a == k) {
Some(pos) => Some(self.0.remove(pos).1),
None => None,
}
}
pub fn contains_key(&self, k: &K) -> bool {
self.get(k).is_some()
}
pub fn is_full(&self) -> bool {
self.0.len() == self.0.capacity()
}
pub fn iter(&self) -> StackMapIter<'_, K, V> {
StackMapIter {
inner: self.0.as_slice().iter(),
}
}
pub fn iter_mut(&mut self) -> StackMapMutIter<'_, K, V> {
StackMapMutIter {
inner: self.0.as_mut_slice().iter_mut(),
}
}
pub fn into_iter(self) -> StackMapIntoIter<K, V> {
StackMapIntoIter {
inner: self.0.into_iter(),
}
}
}
pub struct StackMapMutIter<'a, K: Eq, V> {
inner: std::slice::IterMut<'a, (K, V)>,
}
impl<'a, K: Eq, V> Iterator for StackMapMutIter<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (&*k, v))
}
}
pub struct StackMapIntoIter<K: Eq, V> {
inner: StackVecIntoIter<'static, (K, V)>,
}
impl<K: Eq, V> Iterator for StackMapIntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
pub struct StackMapIter<'a, K: Eq, V> {
inner: std::slice::Iter<'a, (K, V)>,
}
impl<'a, K: Eq, V> Iterator for StackMapIter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (k, v))
}
}
impl<K: Eq + Debug, V: Debug> Debug for StackMap<K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0
.iter()
.fold(&mut f.debug_map(), |acc, (k, v)| acc.entry(k, v))
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let map: StackMap<i32, String> = StackMap::new();
assert!(!map.contains_key(&1));
}
#[test]
fn test_insert_and_get() {
let mut map = StackMap::new();
assert_eq!(map.insert("key1", 42), None);
assert_eq!(map.get(&"key1"), Some(&42));
assert_eq!(map.insert("key2", 24), None);
assert_eq!(map.get(&"key2"), Some(&24));
assert_eq!(map.insert("key1", 100), Some(42));
assert_eq!(map.get(&"key1"), Some(&100));
}
#[test]
fn test_get_nonexistent() {
let map: StackMap<i32, String> = StackMap::new();
assert_eq!(map.get(&1), None);
}
#[test]
fn test_get_mut() {
let mut map = StackMap::new();
map.insert("key", 42);
if let Some(value) = map.get_mut(&"key") {
*value = 100;
}
assert_eq!(map.get(&"key"), Some(&100));
assert_eq!(map.get_mut(&"nonexistent"), None);
}
#[test]
fn test_remove() {
let mut map = StackMap::new();
map.insert("key1", 42);
map.insert("key2", 24);
assert_eq!(map.remove(&"key1"), Some(42));
assert_eq!(map.get(&"key1"), None);
assert_eq!(map.get(&"key2"), Some(&24));
assert_eq!(map.remove(&"nonexistent"), None);
assert_eq!(map.remove(&"key2"), Some(24));
assert_eq!(map.get(&"key2"), None);
}
#[test]
fn test_contains_key() {
let mut map = StackMap::new();
assert!(!map.contains_key(&"key"));
map.insert("key", 42);
assert!(map.contains_key(&"key"));
map.remove(&"key");
assert!(!map.contains_key(&"key"));
}
#[test]
fn test_map_clone() {
let mut map1 = StackMap::new();
map1.insert(1u8, 42);
map1.insert(2u8, 24);
let map2 = map1.clone();
assert_eq!(map2.get(&1u8), Some(&42));
assert_eq!(map2.get(&2u8), Some(&24));
map1.insert(3u8, 100);
assert_eq!(map1.get(&3u8), Some(&100));
assert_eq!(map2.get(&3u8), None);
}
#[test]
fn test_multiple_operations() {
let mut map = StackMap::new();
map.insert(1u8, 1u8);
map.insert(2, 2);
map.insert(3, 3);
assert!(map.contains_key(&1));
assert!(map.contains_key(&2));
assert!(map.contains_key(&3));
map.remove(&2);
assert!(!map.contains_key(&2));
map.insert(1, 11); assert_eq!(map.get(&1), Some(&11));
map.insert(4, 4);
assert_eq!(map.get(&4), Some(&4));
}
#[test]
fn test_iter() {
let mut map = StackMap::new();
map.insert(1u8, 42u8);
map.insert(2, 24);
map.insert(3, 100);
let mut collected: Vec<_> = map.iter().collect();
collected.sort_by_key(|(k, _)| *k);
assert_eq!(collected, vec![(&1, &42), (&2, &24), (&3, &100)]);
}
#[test]
fn test_iter_mut() {
let mut map = StackMap::new();
map.insert(1u8, 42u8);
map.insert(2, 24);
map.insert(3, 100);
for (_, value) in map.iter_mut() {
*value *= 2;
}
assert_eq!(map.get(&1), Some(&84));
assert_eq!(map.get(&2), Some(&48));
assert_eq!(map.get(&3), Some(&200));
}
#[test]
fn test_into_iter() {
let mut map = StackMap::new();
map.insert(1u8, 42u8);
map.insert(2, 24);
map.insert(3, 100);
let mut collected: Vec<_> = map.into_iter().collect();
collected.sort_by_key(|(k, _)| *k);
assert_eq!(collected, vec![(1, 42), (2, 24), (3, 100)]);
}
}