use core::fmt::Debug;
use std::borrow::Borrow;

pub struct VecMap<K, V> {
	items: Vec<(K, V)>,
}

impl<K, V> Debug for VecMap<K, V>
where
	K: Debug,
	V: Debug,
{
	fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
		fmt.debug_map()
			.entries(self.iter().map(|&(ref k, ref v)| (k, v)))
			.finish()
	}
}

impl<K, V> Default for VecMap<K, V> {
	fn default() -> Self {
		Self::new()
	}
}
impl<K, V> VecMap<K, V> {
	pub fn new() -> Self {
		Self { items: vec![] }
	}

	pub fn iter(&self) -> impl Iterator<Item = &(K, V)> {
		self.items.iter()
	}
}

impl<K, V> VecMap<K, V>
where
	K: Eq,
{
	pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
	where
		K: Borrow<Q>,
		Q: Eq + ?Sized,
	{
		self.items
			.iter_mut()
			.find(|(ki, _)| ki.borrow() == k)
			.map(|(_, v)| v)
	}

	pub fn get<Q>(&self, k: &Q) -> Option<&V>
	where
		K: Borrow<Q>,
		Q: Eq + ?Sized,
	{
		self.items
			.iter()
			.find(|(ki, _)| ki.borrow() == k)
			.map(|(_, v)| v)
	}

	pub fn insert(&mut self, k: K, mut v: V) -> Option<V> {
		if let Some(vi) = self.get_mut(&k) {
			core::mem::swap(vi, &mut v);

			return Some(v);
		}

		self.items.push((k, v));
		None
	}
}
