use std::{
any::Any,
collections::{HashMap, hash_map::Entry},
fmt,
sync::Arc,
};
use uuid::Uuid;
pub type AnyBox = Box<dyn Any + Send + Sync + 'static>;
pub type AnyEntry = Arc<tokio::sync::RwLock<Option<AnyBox>>>;
type AnyMap = HashMap<Uuid, AnyEntry>;
#[derive(Clone)]
pub struct AnyStorage {
entries: Arc<std::sync::Mutex<AnyMap>>,
}
impl fmt::Debug for AnyStorage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let entries = self.entries.lock().unwrap();
write!(f, "{:?}", *entries)
}
}
impl AnyStorage {
pub(crate) fn new() -> Self {
Self { entries: Arc::new(std::sync::Mutex::new(AnyMap::new())) }
}
pub fn insert(&self, entry: AnyEntry) -> Uuid {
let mut entries = self.entries.lock().unwrap();
loop {
let key = Uuid::new_v4();
if let Entry::Vacant(e) = entries.entry(key) {
e.insert(entry);
return key;
}
}
}
pub fn get(&self, key: Uuid) -> Option<AnyEntry> {
let entries = self.entries.lock().unwrap();
entries.get(&key).cloned()
}
pub fn remove(&self, key: Uuid) -> Option<AnyEntry> {
let mut entries = self.entries.lock().unwrap();
entries.remove(&key)
}
}