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 let data = self
78 .index
79 .get(&rid)
80 .map(|rc| rc.value().clone())
81 .and_then(|rc| rc.downcast_arc::<T>().cloned());
82 data
83 }
84
85 pub fn get_any(
87 &self,
88 rid: ResourceId,
89 ) -> Option<Arc<dyn Resource>> {
90 self.index.get(&rid).map(|rc| rc.value().clone())
91 }
92
93 pub fn take<T: Resource>(
95 &self,
96 rid: ResourceId,
97 ) -> Option<Arc<T>> {
98 let (_, resource) = self.index.remove(&rid)?;
99 match resource.downcast_arc::<T>() {
100 Some(resource) => Some(resource.clone()),
101 None => None,
102 }
103 }
104
105 pub fn take_any(
107 &self,
108 rid: ResourceId,
109 ) -> Option<Arc<dyn Resource>> {
110 self.index.remove(&rid).map(|rc| rc.1)
111 }
112}
113
114#[derive(Debug, thiserror::Error)]
116pub enum ResourceError {
117 #[error("null or invalid handle")]
118 Reference,
119 #[error("Bad resource ID")]
120 BadResourceId,
121 #[error("Resource is unavailable because it is in use by a promise")]
122 Unavailable,
123 #[error("{0}")]
124 Other(String),
125}