use crate::cacheable::Cacheable;
use crate::punnu::Punnu;
use crate::sassi::trait_registry::TraitRegistry;
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
pub struct Sassi {
pools: RwLock<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
trait_registry: TraitRegistry,
}
impl Sassi {
pub fn new() -> Self {
Self {
pools: RwLock::new(HashMap::new()),
trait_registry: TraitRegistry::new(),
}
}
pub fn register<T>(&mut self, pool: Arc<Punnu<T>>)
where
T: Cacheable + 'static,
{
self.pools
.write()
.expect("Sassi pool registry lock poisoned")
.insert(TypeId::of::<T>(), pool);
}
pub fn pool<T>(&self) -> Option<Arc<Punnu<T>>>
where
T: Cacheable + 'static,
{
let erased = self
.pools
.read()
.expect("Sassi pool registry lock poisoned")
.get(&TypeId::of::<T>())
.cloned()?;
Arc::downcast::<Punnu<T>>(erased).ok()
}
pub fn all_impl<Trait>(&self) -> Vec<Arc<Trait>>
where
Trait: ?Sized + Send + Sync + 'static,
{
self.trait_registry.collect_for::<Trait>(self)
}
}
impl Default for Sassi {
fn default() -> Self {
Self::new()
}
}