kit_rs/config/
repository.rs

1use std::any::{Any, TypeId};
2use std::collections::HashMap;
3use std::sync::{OnceLock, RwLock};
4
5/// Global config repository - stores config instances by type
6static CONFIG_REPOSITORY: OnceLock<RwLock<ConfigRepository>> = OnceLock::new();
7
8/// Repository for storing typed configuration structs
9pub struct ConfigRepository {
10    configs: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
11}
12
13impl ConfigRepository {
14    /// Create a new empty config repository
15    pub fn new() -> Self {
16        Self {
17            configs: HashMap::new(),
18        }
19    }
20
21    /// Register a config struct in the repository
22    pub fn register<T: Any + Send + Sync + 'static>(&mut self, config: T) {
23        self.configs.insert(TypeId::of::<T>(), Box::new(config));
24    }
25
26    /// Get a config struct by type
27    pub fn get<T: Any + Send + Sync + Clone + 'static>(&self) -> Option<T> {
28        self.configs
29            .get(&TypeId::of::<T>())
30            .and_then(|boxed| boxed.downcast_ref::<T>())
31            .cloned()
32    }
33
34    /// Check if a config type is registered
35    pub fn has<T: Any + 'static>(&self) -> bool {
36        self.configs.contains_key(&TypeId::of::<T>())
37    }
38}
39
40impl Default for ConfigRepository {
41    fn default() -> Self {
42        Self::new()
43    }
44}
45
46/// Initialize the global config repository
47pub fn init_repository() -> &'static RwLock<ConfigRepository> {
48    CONFIG_REPOSITORY.get_or_init(|| RwLock::new(ConfigRepository::new()))
49}
50
51/// Register a config in the global repository
52pub fn register<T: Any + Send + Sync + 'static>(config: T) {
53    let repo = init_repository();
54    if let Ok(mut repo) = repo.write() {
55        repo.register(config);
56    }
57}
58
59/// Get a config from the global repository
60pub fn get<T: Any + Send + Sync + Clone + 'static>() -> Option<T> {
61    let repo = CONFIG_REPOSITORY.get()?;
62    repo.read().ok()?.get::<T>()
63}
64
65/// Check if a config type is registered in the global repository
66pub fn has<T: Any + 'static>() -> bool {
67    CONFIG_REPOSITORY
68        .get()
69        .and_then(|repo| repo.read().ok())
70        .map(|repo| repo.has::<T>())
71        .unwrap_or(false)
72}