You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.2 KiB

//! Arbitrary object store
use std::any::{
TypeId,
Any,
};
use std::collections::HashMap;
/// Arbitrarily typed singleton store.
///
/// Stores one object per type.
#[derive(Debug)]
pub struct SingletonStore
{
objects: HashMap<TypeId, Box<dyn Any + 'static>>,
}
#[inline] fn unbox_to<T: Any>(b: Box<dyn Any + 'static>) -> Option<T>
{
b.downcast().map(|ok| *ok).ok()
}
impl SingletonStore
{
pub fn has<T: Any>(&self) -> bool
{
self.objects.contains_key(&TypeId::of::<T>())
}
pub fn remove<T: Any>(&mut self) -> Option<T>
{
self.objects.remove(&TypeId::of::<T>())
.and_then(|x| x.downcast().ok())
.map(|x| *x)
}
pub fn insert<T: Any>(&mut self, value: T) -> Option<T>
{
self.objects.insert(TypeId::of::<T>(), Box::new(value))
.and_then(unbox_to)
}
pub fn get_mut<T: Any>(&mut self) -> Option<&mut T>
{
self.objects.get_mut(&TypeId::of::<T>())
.and_then(|x| x.downcast_mut())
}
pub fn get<T: Any>(&self) -> Option<&T>
{
self.objects.get(&TypeId::of::<T>())
.and_then(|x| x.downcast_ref())
}
pub fn new() -> Self
{
Self {
objects: HashMap::new(),
}
}
}