use std::any::{type_name, TypeId};
use std::collections::HashMap;
use std::ops::ControlFlow;
use crate::logical::registration_id::RegistrationId;
use crate::logical::registry::Registry;
use crate::logical::registry_entry::RegistryEntry;
use crate::raw::{RegistryEntry as RawRegistryEntry};
pub trait Index<R: Registry + ?Sized>: 'static {
type Storage: 'static
+ Sync
+ Send;
fn allocate() -> Self::Storage;
fn associate(
storage: &mut Self::Storage,
id: RegistrationId<R>,
entry: RegistryEntry<R>
) -> ControlFlow<()>;
}
impl<R: Registry + ?Sized> Index<R> for RawRegistryEntry {
type Storage = HashMap<TypeId, RegistrationId<R>>;
fn allocate() -> Self::Storage {
HashMap::new()
}
fn associate(
storage: &mut Self::Storage,
id: RegistrationId<R>,
entry: RegistryEntry<R>
) -> ControlFlow<()> {
if storage.insert(entry.raw().type_id(), id).is_some() {
let registry = type_name::<R>();
let name = entry.raw().type_name();
panic!("duplicate '{registry}' registration for '{name}'")
};
ControlFlow::Continue(())
}
}