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

ambee/giterated

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

So. Much. Work.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨b05f964

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