use {
std::{
any::{Any, TypeId},
collections::HashMap,
sync::Arc,
},
tokio::sync::RwLock,
};
type AnyMap = HashMap<TypeId, Box<dyn Any + Send + Sync>>;
#[derive(Debug, Clone, Default)]
pub struct State(Arc<RwLock<AnyMap>>);
impl State {
pub async fn get<T>(&self) -> Option<T>
where
T: Clone + 'static,
{
self.0
.read()
.await
.get(&TypeId::of::<T>())
.and_then(|value| value.downcast_ref::<T>().cloned())
}
pub async fn insert<T>(&self, value: T) -> Option<T>
where
T: Send + Sync + 'static,
{
self.0
.write()
.await
.insert(TypeId::of::<T>(), Box::new(value))
.and_then(|value| value.downcast::<T>().ok())
.map(|value| *value)
}
pub async fn update<T: 'static>(&self, update: impl Fn(&mut T)) {
if let Some(value) = self
.0
.write()
.await
.get_mut(&TypeId::of::<T>())
.and_then(|value| value.downcast_mut::<T>())
{
update(value);
}
}
pub async fn contains<T: 'static>(&self) -> bool {
self.0.read().await.contains_key(&TypeId::of::<T>())
}
pub async fn remove<T: 'static>(&self) -> Option<T> {
self.0
.write()
.await
.remove(&TypeId::of::<T>())
.and_then(|value| value.downcast::<T>().ok())
.map(|value| *value)
}
}