use std::{any::Any, collections::HashMap};
use dces::prelude::Component;
#[derive(Default)]
pub struct Registry {
registry: HashMap<String, Box<dyn Any>>,
}
impl Registry {
pub fn new() -> Self {
Registry::default()
}
pub fn register<C: Component>(&mut self, key: impl Into<String>, service: C) {
self.registry.insert(key.into(), Box::new(service));
}
pub fn get<C: Component>(&self, key: &str) -> &C {
self.registry
.get(&key.to_string())
.unwrap_or_else(|| panic!("Registry.get(): key: {} could not be found.", key))
.downcast_ref()
.unwrap_or_else(|| panic!("Registry.get(): wrong type for key: {}", key))
}
pub fn get_mut<C: Component>(&mut self, key: &str) -> &mut C {
self.registry
.get_mut(&key.to_string())
.unwrap_or_else(|| panic!("Registry.get(): key: {} could not be found.", key))
.downcast_mut()
.unwrap_or_else(|| panic!("Registry.get(): wrong type for key: {}", key))
}
pub fn try_get<C: Component>(&self, key: &str) -> Option<&C> {
if let Some(e) = self.registry.get(&key.to_string()) {
if let Some(r) = e.downcast_ref() {
return Some(r);
}
}
None
}
pub fn try_get_mut<C: Component>(&mut self, key: &str) -> Option<&mut C> {
if let Some(e) = self.registry.get_mut(&key.to_string()) {
if let Some(r) = e.downcast_mut() {
return Some(r);
}
}
None
}
pub fn len(&self) -> usize {
self.registry.len()
}
pub fn is_empty(&self) -> bool {
self.registry.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
struct ServiceOne;
struct ServiceTwo;
#[test]
fn register() {
let mut registry = Registry::new();
registry.register("one", ServiceOne);
registry.register("two", ServiceTwo);
assert!(registry.try_get::<ServiceOne>("one").is_some());
assert!(registry.try_get::<ServiceTwo>("two").is_some());
}
#[test]
fn try_get_mut() {
let mut registry = Registry::new();
registry.register("one", ServiceOne);
registry.register("two", ServiceTwo);
assert!(registry.try_get_mut::<ServiceOne>("one").is_some());
assert!(registry.try_get_mut::<ServiceTwo>("two").is_some());
}
#[test]
fn len() {
let mut registry = Registry::new();
assert_eq!(registry.len(), 0);
registry.register("one", ServiceOne);
assert_eq!(registry.len(), 1);
registry.register("two", ServiceTwo);
assert_eq!(registry.len(), 2);
}
#[test]
fn is_empty() {
let mut registry = Registry::new();
assert!(registry.is_empty());
registry.register("one", ServiceOne);
assert!(!registry.is_empty());
}
}