use std::{
any::{Any, TypeId},
collections::HashMap,
sync::Arc,
};
use thiserror::Error;
#[derive(Clone, Copy, Debug, Eq, Error, PartialEq)]
pub enum ServiceRegistryError {
#[error("a service of this type is already registered")]
Duplicate,
}
#[derive(Clone, Default)]
pub struct ServiceRegistry {
entries: HashMap<TypeId, Arc<dyn Any + Send + Sync>>,
}
impl ServiceRegistry {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn register<T: Any + Send + Sync>(
&mut self,
service: T,
) -> Result<(), ServiceRegistryError> {
if self.entries.contains_key(&TypeId::of::<T>()) {
return Err(ServiceRegistryError::Duplicate);
}
self.entries.insert(TypeId::of::<T>(), Arc::new(service));
Ok(())
}
#[must_use]
pub fn get<T: Any + Send + Sync>(&self) -> Option<&T> {
self.entries.get(&TypeId::of::<T>())?.downcast_ref()
}
}