use crate::TypeInfo;
use alloc::vec::Vec;
#[derive(Clone, Debug)]
pub struct TypeMap<T> {
entries: Vec<(TypeInfo, T)>,
}
impl<T> TypeMap<T> {
pub fn new() -> Self {
TypeMap {
entries: Vec::new(),
}
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
fn position(&self, id: core::any::TypeId) -> Option<usize> {
self.entries.iter().position(|(info, _)| info.id() == id)
}
pub fn insert<U: 'static>(&mut self, value: T) -> Option<T> {
let info = TypeInfo::of::<U>();
match self.position(info.id()) {
Some(pos) => Some(core::mem::replace(&mut self.entries[pos].1, value)),
None => {
self.entries.push((info, value));
None
}
}
}
pub fn remove<U: 'static>(&mut self) -> Option<T> {
let info = TypeInfo::of::<U>();
let pos = self.position(info.id())?;
Some(self.entries.remove(pos).1)
}
pub fn contains<U: 'static>(&self) -> bool {
self.position(TypeInfo::of::<U>().id()).is_some()
}
pub fn get<U: 'static>(&self) -> Option<&T> {
self
.position(TypeInfo::of::<U>().id())
.map(|pos| &self.entries[pos].1)
}
pub fn get_mut<U: 'static>(&mut self) -> Option<&mut T> {
self
.position(TypeInfo::of::<U>().id())
.map(|pos| &mut self.entries[pos].1)
}
pub fn type_names(&self) -> impl Iterator<Item = &'static str> + '_ {
self.entries.iter().map(|(info, _)| info.name())
}
pub fn iter(&self) -> impl Iterator<Item = (&TypeInfo, &T)> {
self.entries.iter().map(|(info, value)| (info, value))
}
}
impl<T> Default for TypeMap<T> {
fn default() -> Self {
Self::new()
}
}