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

ambee/giterated

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

Before

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨e432306

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