use alloc::vec::Vec;
use core::mem;
use core::ops::Index;
#[derive(Debug)]
pub struct LinearMap<K, V>(
Vec<(K, V)>,
);
impl<K, V> Default for LinearMap<K, V> {
fn default() -> Self {
Self(Default::default())
}
}
impl<K: Eq, V> LinearMap<K, V> {
#[inline]
fn index_of(&self, k: &K) -> Option<usize> {
self.0.iter().position(|(kk, _)| kk == k)
}
pub fn new() -> Self {
Default::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
pub fn get(&self, k: &K) -> Option<&V> {
self.index_of(k).map(|idx| &self.0[idx].1)
}
pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
self.index_of(k).map(|idx| &mut self.0[idx].1)
}
pub fn insert(&mut self, k: K, mut v: V) -> Option<V> {
if let Some(vv) = self.get_mut(&k) {
mem::swap(&mut v, vv);
Some(v)
} else {
self.0.push((k, v));
None
}
}
pub fn get_or_insert_with(&mut self, k: K, f: impl FnOnce() -> V) -> &mut V {
if let Some(idx) = self.index_of(&k) {
&mut self.0[idx].1
} else {
self.0.push((k, f()));
&mut self.0.last_mut().unwrap().1
}
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.0.iter().map(|(_, v)| v)
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.0.iter().map(|(k, _)| k)
}
pub fn iter(&self) -> impl Iterator<Item = &(K, V)> {
self.0.iter()
}
}
impl<K: Eq, V> FromIterator<(K, V)> for LinearMap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut me = Self::default();
for (k, v) in iter {
me.insert(k, v);
}
me
}
}
impl<K, V> IntoIterator for LinearMap<K, V> {
type Item = (K, V);
type IntoIter = <Vec<(K, V)> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<K: Eq, V> Index<&K> for LinearMap<K, V> {
type Output = V;
fn index(&self, index: &K) -> &Self::Output {
self.get(index).unwrap()
}
}
impl<'a, K, V> IntoIterator for &'a LinearMap<K, V> {
type Item = &'a (K, V);
type IntoIter = <&'a Vec<(K, V)> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
#[cfg(test)]
mod tests {
use alloc::vec;
use super::*;
#[test]
fn test_index_of() {
let mut map = LinearMap::new();
assert_eq!(map.index_of(&1), None);
map.insert(1, "a");
map.insert(2, "b");
assert_eq!(map.index_of(&1), Some(0));
assert_eq!(map.index_of(&2), Some(1));
assert_eq!(map.index_of(&3), None);
}
#[test]
fn test_index_of_after_overwrite() {
let mut map = LinearMap::new();
map.insert(1, "a");
map.insert(2, "b");
assert_eq!(map.insert(1, "c"), Some("a"));
assert_eq!(map.index_of(&1), Some(0));
assert_eq!(map.get(&1), Some(&"c"));
}
#[test]
fn test_insert_and_get() {
let mut map = LinearMap::new();
assert_eq!(map.insert(1, "a"), None);
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.insert(1, "b"), Some("a"));
assert_eq!(map.get(&1), Some(&"b"));
assert_eq!(map.get(&2), None);
}
#[test]
fn test_get_mut() {
let mut map = LinearMap::new();
map.insert(42, 100);
if let Some(val) = map.get_mut(&42) {
*val += 1;
}
assert_eq!(map.get(&42), Some(&101));
assert_eq!(map.get_mut(&999), None);
}
#[test]
fn test_get_or_insert_with() {
let mut map = LinearMap::new();
let val = map.get_or_insert_with(10, || 123);
assert_eq!(*val, 123);
let val2 = map.get_or_insert_with(10, || panic!("should not be called"));
assert_eq!(*val2, 123);
let val3 = map.get_or_insert_with(20, || 777);
assert_eq!(*val3, 777);
}
#[test]
fn test_values_iterator() {
let mut map = LinearMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let values: Vec<_> = map.values().copied().collect();
assert_eq!(values, vec![1, 2, 3]);
}
#[test]
fn test_keys_iterator() {
let mut map = LinearMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let values: Vec<_> = map.keys().copied().collect();
assert_eq!(values, vec!["a", "b", "c"]);
}
#[test]
fn test_index() {
let mut map = LinearMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
assert_eq!(map[&"a"], 1);
assert_eq!(map[&"b"], 2);
assert_eq!(map[&"c"], 3);
}
#[test]
fn test_from_iterator_behavior() {
let map: LinearMap<_, _> = vec![(1, "a"), (2, "b"), (1, "c")].into_iter().collect();
assert_eq!(map.get(&1), Some(&"c"));
assert_eq!(map.get(&2), Some(&"b"));
}
#[test]
fn test_into_iterator() {
let mut map = LinearMap::new();
map.insert("x", 10);
map.insert("z", 30);
map.insert("y", 20);
let iter_ref = map.iter().copied().collect::<Vec<_>>();
let iter = map.into_iter().collect::<Vec<_>>();
assert_eq!(iter_ref, vec![("x", 10), ("z", 30), ("y", 20)]);
assert_eq!(iter, iter_ref);
}
#[test]
fn test_empty_map_behavior() {
let map: LinearMap<i32, &str> = LinearMap::new();
assert_eq!(map.get(&0), None);
assert_eq!(map.get(&999), None);
assert_eq!(map.values().count(), 0);
}
}