mf_state/
resource_table.rs1use std::sync::Arc;
2use std::fmt::{self, Debug};
3
4use dashmap::DashMap;
5
6use crate::resource::Resource;
7
8pub type ResourceId = String;
10
11#[derive(Default)]
13pub struct ResourceTable {
14 index: DashMap<ResourceId, Arc<dyn Resource>>,
16}
17impl Debug for ResourceTable {
18 fn fmt(
19 &self,
20 f: &mut fmt::Formatter<'_>,
21 ) -> fmt::Result {
22 write!(f, "ResourceTable {{ len: {} }}", self.index.len())
23 }
24}
25impl ResourceTable {
26 pub fn len(&self) -> usize {
28 self.index.len()
29 }
30
31 pub fn is_empty(&self) -> bool {
33 self.index.is_empty()
34 }
35
36 pub fn add<T: Resource>(
38 &self,
39 rid: ResourceId,
40 resource: T,
41 ) {
42 self.add_arc(rid, Arc::new(resource));
43 }
44
45 pub fn add_arc<T: Resource>(
47 &self,
48 rid: ResourceId,
49 resource: Arc<T>,
50 ) {
51 let resource = resource as Arc<dyn Resource>;
52 self.add_arc_dyn(rid, resource);
53 }
54
55 pub fn add_arc_dyn(
57 &self,
58 rid: ResourceId,
59 resource: Arc<dyn Resource>,
60 ) {
61 self.index.insert(rid, resource);
62 }
63
64 pub fn has(
66 &self,
67 rid: ResourceId,
68 ) -> bool {
69 self.index.contains_key(&rid)
70 }
71
72 pub fn get<T: Resource>(
74 &self,
75 rid: ResourceId,
76 ) -> Option<Arc<T>> {
77 self.index
78 .get(&rid)
79 .map(|rc| rc.value().clone())
80 .and_then(|rc| rc.downcast_arc::<T>().cloned())
81 }
82
83 pub fn get_any(
85 &self,
86 rid: ResourceId,
87 ) -> Option<Arc<dyn Resource>> {
88 self.index.get(&rid).map(|rc| rc.value().clone())
89 }
90
91 pub fn take<T: Resource>(
93 &self,
94 rid: ResourceId,
95 ) -> Option<Arc<T>> {
96 let (_, resource) = self.index.remove(&rid)?;
97 resource.downcast_arc::<T>().cloned()
98 }
99
100 pub fn take_any(
102 &self,
103 rid: ResourceId,
104 ) -> Option<Arc<dyn Resource>> {
105 self.index.remove(&rid).map(|rc| rc.1)
106 }
107}
108
109#[derive(Debug, thiserror::Error)]
111pub enum ResourceError {
112 #[error("null or invalid handle")]
113 Reference,
114 #[error("Bad resource ID")]
115 BadResourceId,
116 #[error("Resource is unavailable because it is in use by a promise")]
117 Unavailable,
118 #[error("{0}")]
119 Other(String),
120}