khora_core/utils/
any_map.rs1use std::any::{Any, TypeId};
21use std::collections::HashMap;
22use std::sync::Arc;
23
24pub struct AnyMap {
26 data: HashMap<TypeId, Arc<dyn Any + Send + Sync>>,
27}
28
29impl AnyMap {
30 pub fn new() -> Self {
32 Self {
33 data: HashMap::new(),
34 }
35 }
36
37 pub fn insert<T: Send + Sync + 'static>(&mut self, value: T) {
39 self.data.insert(TypeId::of::<T>(), Arc::new(value));
40 }
41
42 pub fn get<T: Send + Sync + 'static>(&self) -> Option<Arc<T>> {
44 self.data
45 .get(&TypeId::of::<T>())
46 .and_then(|v| v.clone().downcast::<T>().ok())
47 }
48
49 pub fn contains<T: Send + Sync + 'static>(&self) -> bool {
51 self.data.contains_key(&TypeId::of::<T>())
52 }
53
54 pub fn remove<T: Send + Sync + 'static>(&mut self) -> Option<Arc<T>> {
56 self.data
57 .remove(&TypeId::of::<T>())
58 .and_then(|v| v.downcast::<T>().ok())
59 }
60}
61
62impl Default for AnyMap {
63 fn default() -> Self {
64 Self::new()
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_insert_and_get() {
74 let mut map = AnyMap::new();
75 map.insert(42u32);
76 assert_eq!(*map.get::<u32>().unwrap(), 42);
77 }
78
79 #[test]
80 fn test_replace() {
81 let mut map = AnyMap::new();
82 map.insert("hello");
83 map.insert("world");
84 assert_eq!(*map.get::<&str>().unwrap(), "world");
85 }
86
87 #[test]
88 fn test_missing_type() {
89 let map = AnyMap::new();
90 assert!(map.get::<u32>().is_none());
91 }
92
93 #[test]
94 fn test_contains() {
95 let mut map = AnyMap::new();
96 map.insert(true);
97 assert!(map.contains::<bool>());
98 assert!(!map.contains::<u32>());
99 }
100}