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

ambee/giterated

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

Huge refactor to prep for moving the daemon over to the plugin architecture

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5df753c

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