use std::any::{Any, TypeId};
use std::collections::HashMap;
use once_cell::sync::OnceCell;
use crate::contracts::Facade;
pub struct Container(HashMap<TypeId, Box<dyn Any + Send + Sync>>);
impl Default for Container {
fn default() -> Self {
Self::new()
}
}
impl Container {
pub fn new() -> Self {
Container(HashMap::new())
}
pub fn register<T: Facade>(&mut self) {
self.0.insert(TypeId::of::<T>(), Box::new(T::new(self)));
}
pub fn get<T: Facade>(&self) -> Option<&T> {
self.0
.get(&TypeId::of::<T>())
.and_then(|boxed| boxed.downcast_ref::<T>())
}
pub fn get_mut<T: Facade>(&mut self) -> Option<&mut T> {
self.0
.get_mut(&TypeId::of::<T>())
.and_then(|boxed| boxed.downcast_mut::<T>())
}
pub fn into_static(self) -> &'static Container {
CONTAINER.get_or_init(|| self)
}
}
static CONTAINER: OnceCell<Container> = OnceCell::new();
pub fn container() -> &'static Container {
CONTAINER.get().expect("Container not initialized")
}