JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

More restructuring

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨10b7b7c

⁨giterated-runtime/src/operation_walker.rs⁩ - ⁨9734⁩ bytes
Raw
1 use giterated_abi::{result::FfiError, value_ex::FfiValueUntyped, vtable::runtime::RuntimeHandle};
2 use giterated_models::{
3 error::OperationError, object::ObjectOperationPair, operation::GiteratedOperation,
4 settings::GetSetting, value::GetValue,
5 };
6
7 use tracing::{debug_span, trace, trace_span};
8
9 use super::{ObjectSettingPair, ObjectValuePair, RuntimeHandlers};
10
11 /// A wrapper for operation handling that enforces handling rules.
12 ///
13 /// # Handler Resolution
14 /// In order, handler resolution will be attempted as follows:
15 ///
16 /// | Index | object_kind | operation_kind | Special Case? |
17 /// |-------|-------------|-----------------|---------------|
18 /// | 1 | `any` | `typed` | No |
19 /// | 2 | `typed` | `any` | No |
20 /// | 3 | `any` | `any` | No |
21 /// | 4 | `any` | `GetValue` | ⚠️ Yes ⚠️ |
22 /// | 5 | `any` | `GetSetting` | ⚠️ Yes ⚠️ |
23 /// | 6 | `any` | `SetSetting` | ⚠️ Yes ⚠️ |
24 /// | 7 | `any` | `ObjectRequest` | ⚠️ Yes ⚠️ |
25 /// | 8 | `typed` | `typed` | No |
26 pub struct OperationHandlerRules<'a> {
27 object_kind: &'a str,
28 operation_name: &'a str,
29 handlers: &'a RuntimeHandlers,
30 }
31
32 impl<'o> OperationHandlerRules<'o> {
33 pub fn new(
34 object_kind: &'o str,
35 operation_name: &'o str,
36 handlers: &'o RuntimeHandlers,
37 ) -> Self {
38 Self {
39 object_kind,
40 operation_name,
41 handlers,
42 }
43 }
44
45 pub async fn handle(
46 &self,
47 runtime: &RuntimeHandle,
48 object: &str,
49 operation_payload: &[u8],
50 ) -> Result<FfiValueUntyped, OperationError<FfiError>> {
51 // object_kind: `any`
52 // operation_kind: `typed`
53 if let Some(_handler) = self
54 .handlers
55 .operation_handlers
56 .get(&ObjectOperationPair::new("any", self.operation_name))
57 {
58 todo!()
59 }
60
61 // object_kind: `typed`
62 // operation_kind: `any`
63 if let Some(_handler) = self
64 .handlers
65 .operation_handlers
66 .get(&ObjectOperationPair::new(self.object_kind, "any"))
67 {}
68
69 // object_kind: `any`
70 // operation_kind: `any`
71 if let Some(_handler) = self
72 .handlers
73 .operation_handlers
74 .get(&ObjectOperationPair::new("any", "any"))
75 {}
76
77 // ⚠️ Special Case ⚠️
78 // object_kind: `any`
79 // operation_kind: `GetValue`
80 if self.operation_name == "get_value" {
81 let operation: GetValue = todo!();
82 let _guard = trace_span!(
83 "get_value handler resolving",
84 object = self.object_kind,
85 value = operation.value_name
86 )
87 .entered();
88
89 if let Some((domain, callback)) = self.handlers.value_getters.get(
90 &ObjectValuePair::new(self.object_kind, &operation.value_name),
91 ) {
92 trace_span!(
93 "get_value handler.",
94 object = self.object_kind,
95 value_name = operation.value_name
96 );
97
98 let object_vtable = domain
99 .object_vtable(self.object_kind)
100 .ok_or_else(|| OperationError::Unhandled)?;
101 trace!("Resolved object vtable for {}", self.object_kind);
102
103 let _value_vtable = domain
104 .value_vtable(self.object_kind, &operation.value_name)
105 .ok_or_else(|| OperationError::Unhandled)?;
106 trace!(
107 "Resolved value vtable for {}::{}",
108 self.object_kind,
109 operation.value_name
110 );
111
112 // let object = unsafe { (object_vtable.from_str)(object) }
113 // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?;
114
115 // let _guard = debug_span!("get_value handler");
116
117 // let result = unsafe {
118 // (callback.func)(
119 // callback.callback_ptr,
120 // runtime_state,
121 // &domain.plugin.state,
122 // object,
123 // )
124 // }
125 // .await;
126
127 // match result {
128 // Ok(value) => return Ok(value.into()),
129 // Err(_err) => todo!(),
130 // }
131
132 todo!()
133 } else {
134 trace!("Failed to resolve handler.");
135 }
136 }
137
138 // ⚠️ Special Case ⚠️
139 // object_kind: `any`
140 // operation_kind: `GetSetting`
141 if self.operation_name == "get_setting" {
142 let operation: GetSetting = todo!();
143 let _guard = trace_span!(
144 "get_setting handler resolving",
145 object = self.object_kind,
146 setting = operation.setting_name
147 )
148 .entered();
149
150 if let Some((domain, callback)) = self.handlers.setting_getters.get(
151 &ObjectSettingPair::new(self.object_kind, &operation.setting_name),
152 ) {
153 trace_span!(
154 "get_setting handler.",
155 object = self.object_kind,
156 setting_name = operation.setting_name
157 );
158
159 let object_vtable = domain
160 .object_vtable(self.object_kind)
161 .ok_or_else(|| OperationError::Unhandled)?;
162 trace!("Resolved object vtable for {}", self.object_kind);
163
164 let _setting_vtable = domain
165 .setting_vtable(self.object_kind, &operation.setting_name)
166 .ok_or_else(|| OperationError::Unhandled)?;
167 trace!("Resolved setting vtable for {}", operation.setting_name);
168
169 todo!()
170
171 // let object = unsafe { (object_vtable.from_str)(object) }
172 // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?;
173
174 // let _guard = debug_span!("get_value handler");
175
176 // let result = unsafe {
177 // (callback.func())(
178 // callback.callback_ptr,
179 // runtime_state,
180 // &domain.plugin.state,
181 // object,
182 // )
183 // }
184 // .await;
185
186 // match result {
187 // Ok(value) => {
188 // let vtable = unsafe { (value.vtable.get_setting_vtable)() };
189 // let return_value: Value = serde_json::from_slice(unsafe {
190 // (value.vtable.serialize)(value).unwrap().as_ref()
191 // })
192 // .unwrap();
193
194 // todo!()
195
196 // // return Ok(unsafe {
197 // // AnySuccess::from_raw(
198 // // FFIBox::from_box(Box::new(return_value)).untyped(),
199 // // vtable,
200 // // )
201 // // });
202 // }
203 // Err(_err) => todo!(),
204 // }
205 } else {
206 trace!("Failed to resolve handler.");
207 }
208 }
209
210 // ⚠️ Special Case ⚠️
211 // object_kind: `any`
212 // operation_kind: `SetSetting`
213 self.operation_name == "set_setting";
214
215 // ⚠️ Special Case ⚠️
216 // object_kind: `any`
217 // operation_kind: `ObjectRequest`
218 self.operation_name == "object_request";
219
220 // object_kind: `typed`
221 // operation_kind: `typed`
222 if let Some((domain, handler)) =
223 self.handlers
224 .operation_handlers
225 .get(&ObjectOperationPair::new(
226 self.object_kind,
227 self.operation_name,
228 ))
229 {
230 let _guard = trace_span!("typed_typed handler resolved").entered();
231
232 let object_vtable = domain
233 .object_vtable(self.object_kind)
234 .ok_or_else(|| OperationError::Unhandled)?;
235 trace!("Resolved object vtable for {}", self.object_kind);
236
237 let operation_vtable = domain
238 .operation_vtable(self.object_kind, self.operation_name)
239 .ok_or_else(|| OperationError::Unhandled)?;
240 trace!(
241 "Resolved operation vtable for {}::{}",
242 self.object_kind,
243 self.operation_name
244 );
245
246 todo!()
247
248 // let object = unsafe { (object_vtable.from_str)(object) }
249 // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?;
250 // let operation = unsafe { (operation_vtable.deserialize)(operation_payload) }
251 // .map_err(|_| OperationError::Internal(anyhow::anyhow!("yikes!")))?;
252 // trace!("Parsed operation data");
253
254 // let _guard = debug_span!("calling handler").entered();
255 // let result = unsafe {
256 // (handler.func)(
257 // handler.callback_ptr,
258 // runtime_state,
259 // &domain.plugin.state,
260 // object,
261 // operation,
262 // )
263 // };
264
265 // return result.await;
266 }
267
268 Err(OperationError::Unhandled)
269 }
270 }
271