molframe_core/structure/
extensions.rs1use std::any::Any;
4use std::collections::BTreeMap;
5use std::fmt;
6use std::panic::RefUnwindSafe;
7use std::sync::Arc;
8
9trait ExtensionValue: Send + Sync + RefUnwindSafe {
10 fn as_any(&self) -> &dyn Any;
11 fn into_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
12}
13
14impl<T> ExtensionValue for T
15where
16 T: Any + Send + Sync + RefUnwindSafe,
17{
18 fn as_any(&self) -> &dyn Any {
19 self
20 }
21
22 fn into_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
23 self
24 }
25}
26
27type SharedExtension = Arc<dyn ExtensionValue>;
28
29#[derive(Clone, Default)]
34pub struct ExtensionStore {
35 values: BTreeMap<&'static str, SharedExtension>,
36}
37
38impl ExtensionStore {
39 #[must_use]
41 pub const fn new() -> Self {
42 Self {
43 values: BTreeMap::new(),
44 }
45 }
46
47 pub fn insert<T>(&mut self, key: &'static str, value: T)
49 where
50 T: Any + Send + Sync + RefUnwindSafe,
51 {
52 let _ = self.values.insert(key, Arc::new(value));
53 }
54
55 #[must_use]
57 pub fn get<T>(&self, key: &str) -> Option<&T>
58 where
59 T: Any + Send + Sync + RefUnwindSafe,
60 {
61 self.values.get(key)?.as_ref().as_any().downcast_ref()
62 }
63
64 #[must_use]
66 pub fn get_shared<T>(&self, key: &str) -> Option<Arc<T>>
67 where
68 T: Any + Send + Sync + RefUnwindSafe,
69 {
70 Arc::clone(self.values.get(key)?).into_any().downcast().ok()
71 }
72
73 pub fn clear(&mut self) {
75 self.values.clear();
76 }
77
78 #[must_use]
80 pub fn is_empty(&self) -> bool {
81 self.values.is_empty()
82 }
83
84 #[must_use]
86 pub fn len(&self) -> usize {
87 self.values.len()
88 }
89
90 pub fn keys(&self) -> impl Iterator<Item = &'static str> + '_ {
92 self.values.keys().copied()
93 }
94}
95
96impl fmt::Debug for ExtensionStore {
97 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
98 formatter
99 .debug_struct("ExtensionStore")
100 .field("keys", &self.values.keys().collect::<Vec<_>>())
101 .finish()
102 }
103}