1pub mod prelude;
6
7use std::any::{type_name, Any, TypeId};
8use std::collections::HashMap;
9use std::fmt::Debug;
10
11pub trait Resource: Any + Debug + Send + Sync + 'static {}
13
14#[derive(Debug)]
16pub struct ResourceStorage {
17 resources: HashMap<TypeId, Box<dyn Any + 'static>>,
18}
19
20impl Default for ResourceStorage {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl ResourceStorage {
27 #[must_use]
29 pub fn new() -> Self {
30 Self {
31 resources: HashMap::new(),
32 }
33 }
34
35 pub fn insert<R: Resource>(&mut self, resource: R) {
39 self.resources.insert(TypeId::of::<R>(), Box::new(resource));
40 }
41
42 #[must_use]
48 pub fn fetch<R: Resource>(&self) -> &R {
49 self.resources
50 .get(&TypeId::of::<R>())
51 .unwrap_or_else(|| panic!("Resource of type '{}' not found.", type_name::<R>()))
52 .downcast_ref::<R>()
53 .expect("Failed to downcast resource to the expected type.")
54 }
55
56 #[must_use]
62 pub fn fetch_mut<R: Resource>(&mut self) -> &mut R {
63 self.resources
64 .get_mut(&TypeId::of::<R>())
65 .unwrap_or_else(|| panic!("Resource of type '{}' not found.", type_name::<R>()))
66 .downcast_mut::<R>()
67 .expect("Failed to downcast resource to the expected type.")
68 }
69
70 #[must_use]
74 pub fn get<R: Resource + 'static>(&self) -> Option<&R> {
75 self.resources
76 .get(&TypeId::of::<R>())
77 .and_then(|boxed_any| boxed_any.downcast_ref::<R>())
78 }
79
80 #[must_use]
84 pub fn get_mut<R: Resource + 'static>(&mut self) -> Option<&mut R> {
85 self.resources
86 .get_mut(&TypeId::of::<R>())
87 .and_then(|boxed_any| boxed_any.downcast_mut::<R>())
88 }
89
90 pub fn remove<R: Resource>(&mut self) -> Option<R> {
98 self.resources.remove(&TypeId::of::<R>()).map(|boxed_any| {
99 *boxed_any
100 .downcast::<R>()
101 .expect("Failed to downcast resource to the expected type.")
102 })
103 }
104
105 #[must_use]
107 pub fn contains<R: Resource>(&self) -> bool {
108 self.resources.contains_key(&TypeId::of::<R>())
109 }
110}