orbit/component/
context.rs1use std::any::{Any, TypeId};
4use std::collections::HashMap;
5use std::fmt::Debug;
6use std::sync::{Arc, RwLock};
7
8#[allow(dead_code)]
10pub trait ContextValue: Any + Send + Sync {
11 fn as_any(&self) -> &dyn Any;
12 fn as_any_mut(&mut self) -> &mut dyn Any;
13 fn box_clone(&self) -> Box<dyn ContextValue>;
14 fn debug_string(&self) -> String;
15}
16
17impl<T: Any + Clone + Send + Sync + Debug + 'static> ContextValue for T {
18 fn as_any(&self) -> &dyn Any {
19 self
20 }
21
22 fn as_any_mut(&mut self) -> &mut dyn Any {
23 self
24 }
25
26 fn box_clone(&self) -> Box<dyn ContextValue> {
27 Box::new(self.clone())
28 }
29 fn debug_string(&self) -> String {
30 format!("{self:?}")
31 }
32}
33
34#[derive(Clone, Default)]
36pub struct ContextProvider {
37 parent: Option<Box<ContextProvider>>,
39 values: Arc<RwLock<HashMap<TypeId, Box<dyn ContextValue>>>>,
40}
41
42impl Debug for ContextProvider {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 f.debug_struct("ContextProvider")
45 .field("parent", &self.parent.is_some())
46 .field(
47 "values",
48 &format!(
49 "[{} values]",
50 self.values.read().map(|v| v.len()).unwrap_or(0)
51 ),
52 )
53 .finish()
54 }
55}
56
57impl ContextProvider {
58 pub fn new() -> Self {
60 Self {
61 parent: None,
62 values: Arc::new(RwLock::new(HashMap::new())),
63 }
64 }
65
66 pub fn with_parent(parent: ContextProvider) -> Self {
68 Self {
69 parent: Some(Box::new(parent)),
70 values: Arc::new(RwLock::new(HashMap::new())),
71 }
72 }
73
74 pub fn provide<T: Clone + Send + Sync + std::fmt::Debug + 'static>(
76 &self,
77 value: T,
78 ) -> Result<(), String> {
79 let type_id = TypeId::of::<T>();
80 if let Ok(mut values) = self.values.write() {
81 values.insert(type_id, Box::new(value));
82 Ok(())
83 } else {
84 Err("Failed to acquire write lock for context values".to_string())
85 }
86 }
87
88 pub fn consume<T: Clone + Send + Sync + 'static>(&self) -> Option<T> {
90 let type_id = TypeId::of::<T>();
91
92 let result = {
94 if let Ok(values) = self.values.read() {
95 if let Some(value) = values.get(&type_id) {
96 value.as_any().downcast_ref::<T>().cloned()
97 } else {
98 None
99 }
100 } else {
101 None
102 }
103 };
104
105 if result.is_some() {
107 return result;
108 }
109
110 if let Some(parent) = &self.parent {
112 parent.consume::<T>()
113 } else {
114 None
115 }
116 }
117
118 pub fn has<T: 'static>(&self) -> bool {
120 let type_id = TypeId::of::<T>();
121
122 let exists_here = {
124 if let Ok(values) = self.values.read() {
125 values.contains_key(&type_id)
126 } else {
127 false
128 }
129 };
130
131 if exists_here {
132 return true;
133 }
134
135 if let Some(parent) = &self.parent {
137 parent.has::<T>()
138 } else {
139 false
140 }
141 }
142
143 pub fn remove<T: 'static>(&self) -> bool {
145 let type_id = TypeId::of::<T>();
146 let result = {
147 if let Ok(mut values) = self.values.write() {
148 values.remove(&type_id).is_some()
149 } else {
150 false
151 }
152 };
153 result
154 }
155}
156
157pub struct Callback<Args, Ret = ()> {
159 func: Arc<dyn Fn(Args) -> Ret + Send + Sync>,
161}
162
163impl<Args: 'static, Ret: 'static> Clone for Callback<Args, Ret> {
164 fn clone(&self) -> Self {
165 Self {
166 func: self.func.clone(),
167 }
168 }
169}
170
171impl<Args, Ret> Callback<Args, Ret> {
172 pub fn new<F>(func: F) -> Self
174 where
175 F: Fn(Args) -> Ret + Send + Sync + 'static,
176 {
177 Self {
178 func: Arc::new(func),
179 }
180 }
181
182 pub fn call(&self, args: Args) -> Ret {
184 (self.func)(args)
185 }
186}
187
188pub fn callback<F, Args, Ret>(func: F) -> Callback<Args, Ret>
190where
191 F: Fn(Args) -> Ret + Send + Sync + 'static,
192{
193 Callback::new(func)
194}