Beginning of `stack-next` refactor
-Refactoring the protocol stack into something similar to a runtime. -Handles merging handler builders which is placing the ground work for plugins in. - Increased metadata generation during compilation enables less ser/de during execution. - Goal is to have an O(1) time from incoming operation to calling handlers. - Decreased penalty for using the statically typed API from within your code, now avoids some allocation. # Changes - Added `GiteratedRuntime` which is to replace the current unified stack - Added `RuntimeBuilder` which does what the current `OperationHandlers` struct does, but much better. - Added `RuntimeMetadata` to store type metadata for new `Any` based internals - Refactored serde_json out of the internal operation handling
parent: tbd commit: 708dea4
1 | use ; |
2 | |
3 | use |
4 | , | AuthenticatedPayload
5 | , | OperationError
6 | , | GiteratedMessage
7 | , |
8 | , |
9 | , |
10 | , |
11 | ; |
12 | use trace; |
13 | |
14 | use crate:: |
15 | GiteratedOperationHandler, ObjectMeta, ObjectOperationPair, ObjectValuePair, OperationMeta, |
16 | OperationWrapper, SettingMeta, StackOperationState, ValueMeta, |
17 | ; |
18 | |
19 | /// Temporary name for the next generation of Giterated stack |
20 | |
21 | operation_handlers: , |
22 | value_getters: , |
23 | setting_getters: , |
24 | metadata: RuntimeMetadata, |
25 | |
26 | |
27 | |
28 | |
29 | for in builder.operation_handlers |
30 | let tree = self.get_or_create_tree; |
31 | |
32 | tree.push; |
33 | |
34 | |
35 | for in builder.value_getters |
36 | assert!; |
37 | |
38 | |
39 | for in builder.setting_getters |
40 | assert!; |
41 | |
42 | |
43 | self.metadata.append; |
44 | |
45 | self |
46 | |
47 | |
48 | |
49 | if self.operation_handlers.contains_key |
50 | self.operation_handlers.get_mut .unwrap |
51 | else |
52 | self.operation_handlers |
53 | .insert; |
54 | |
55 | self.operation_handlers.get_mut .unwrap |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | elements: , |
62 | |
63 | |
64 | |
65 | |
66 | Self |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | self.elements.push; |
73 | |
74 | |
75 | |
76 | &self, |
77 | object: &dyn Any, |
78 | operation: , |
79 | state: &S, |
80 | operation_state: &StackOperationState, |
81 | |
82 | todo! |
83 | |
84 | |
85 | |
86 | /// Stores runtime metadata for all in-use Giterated protocol types. |
87 | |
88 | |
89 | objects: , |
90 | operations: , |
91 | values: , |
92 | settings: , |
93 | |
94 | |
95 | /// Defines a type that is a valid Giterated runtime state. |
96 | /// |
97 | /// This allows for extraction of state in handlers, based on a |
98 | /// [`FromOperationState<S>`] impl on (what is in this case) [`Self`]. |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | operation_handlers: , |
106 | value_getters: , |
107 | setting_getters: , |
108 | metadata: RuntimeMetadata, |
109 | |
110 | |
111 | |
112 | /// Insert an operation handler into the runtime builder. |
113 | /// |
114 | /// # Type Registration |
115 | /// Inserting the handler will automatically, if required, register the operation type of the |
116 | /// handler. It will **not** register the object type automatically. |
117 | |
118 | |
119 | O: GiteratedObject + 'static, |
120 | D: + 'static, |
121 | H: + 'static + Clone, |
122 | |
123 | let object_name = handler.object_name .to_string; |
124 | let operation_name = handler.operation_name .to_string; |
125 | |
126 | let wrapped = new; |
127 | |
128 | let pair = ObjectOperationPair |
129 | object_name, |
130 | operation_name, |
131 | ; |
132 | |
133 | assert!; |
134 | |
135 | self.metadata.; |
136 | |
137 | self |
138 | |
139 | |
140 | /// Register a [`GiteratedObject`] type with the runtime. |
141 | /// |
142 | /// # Type Registration |
143 | /// This will register the provided object type. |
144 | |
145 | self.metadata.; |
146 | |
147 | self |
148 | |
149 | |
150 | /// Register a [`Setting`] type with the runtime. |
151 | /// |
152 | /// # Type Registration |
153 | /// This will register the provided setting type. |
154 | |
155 | self.metadata.; |
156 | |
157 | self |
158 | |
159 | |
160 | /// Register a [`GiteratedObjectValue<O>`] type with the runtime, providing |
161 | /// its associated handler for [`GetValue`]. |
162 | /// |
163 | /// # Type Registration |
164 | /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified |
165 | /// object type. It will **not** register the object type automatically. |
166 | |
167 | |
168 | O: GiteratedObject + 'static, |
169 | V: + 'static, |
170 | F: + Clone + 'static, |
171 | |
172 | let object_name = handler.object_name .to_string; |
173 | let value_name = value_name .to_string; |
174 | |
175 | let wrapped = new; |
176 | |
177 | assert! |
178 | .value_getters |
179 | .insert |
180 | ObjectValuePair |
181 | object_kind: object_name, |
182 | value_kind: value_name |
183 | , |
184 | wrapped |
185 | |
186 | .is_none; |
187 | |
188 | self.metadata.; |
189 | |
190 | self |
191 | |
192 | |
193 | /// Register a handler for [`GetSetting`] for it's associated object type. |
194 | |
195 | |
196 | O: GiteratedObject + 'static, |
197 | F: + Clone + 'static, |
198 | |
199 | let object_name = handler.object_name .to_string; |
200 | |
201 | let wrapped = new; |
202 | |
203 | assert!; |
204 | |
205 | self |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | let object_name = object_name .to_string; |
212 | |
213 | let object_meta = ObjectMeta |
214 | name: object_name.clone, |
215 | from_str: Box new, |
216 | any_is_same: Box new, |
217 | ; |
218 | |
219 | if self.objects.insert .is_some |
220 | trace! |
221 | "Registration of object {} overwrote previous registration.", |
222 | object_name |
223 | ; |
224 | else |
225 | trace! |
226 | |
227 | |
228 | |
229 | |
230 | &mut self, |
231 | |
232 | let object_name = object_name .to_string; |
233 | let operation_name = operation_name .to_string; |
234 | |
235 | if self |
236 | .operations |
237 | .insert |
238 | ObjectOperationPair |
239 | object_name: object_name.clone, |
240 | operation_name: operation_name.clone, |
241 | , |
242 | OperationMeta |
243 | name: operation_name, |
244 | object_kind: object_name, |
245 | deserialize: Box new |
246 | Ok |
247 | as |
248 | , |
249 | any_is_same: Box new, |
250 | serialize_success: Box new |
251 | let to_serialize = any. .unwrap; |
252 | to_vec |
253 | , |
254 | serialize_error: Box new |
255 | let to_serialize = any. .unwrap; |
256 | to_vec |
257 | , |
258 | , |
259 | |
260 | .is_some |
261 | |
262 | trace! |
263 | "Registration of object operation {}<{}> overwrote previous registration.", |
264 | , | operation_name
265 | object_name |
266 | ; |
267 | else |
268 | trace! |
269 | "Registration of object operation {}<{}>.", |
270 | , | operation_name
271 | object_name |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | O: GiteratedObject + 'static, |
278 | V: + 'static, |
279 | > |
280 | &mut self, |
281 | |
282 | let object_name = object_name .to_string; |
283 | let value_name = value_name .to_string; |
284 | |
285 | if self |
286 | .values |
287 | .insert |
288 | ObjectValuePair |
289 | object_kind: object_name.clone, |
290 | value_kind: value_name.clone, |
291 | , |
292 | ValueMeta |
293 | name: value_name, |
294 | deserialize: Box new, |
295 | , |
296 | |
297 | .is_some |
298 | |
299 | trace! |
300 | "Registration of value <{}>::{} overwrote previous registration.", |
301 | , | object_name
302 | value_name |
303 | ; |
304 | else |
305 | trace! |
306 | "Registration of value <{}>::{}.", |
307 | , | object_name
308 | value_name |
309 | ; |
310 | |
311 | |
312 | |
313 | |
314 | let setting_name = name .to_string; |
315 | |
316 | if self |
317 | .settings |
318 | .insert |
319 | setting_name.clone, |
320 | SettingMeta |
321 | name: setting_name, |
322 | deserialize: Box new, |
323 | , |
324 | |
325 | .is_some |
326 | |
327 | trace! |
328 | "Registration of setting {} overwrote previous registration.", |
329 | name |
330 | ; |
331 | else |
332 | trace!; |
333 | |
334 | |
335 | |
336 | |
337 | self.objects.extend; |
338 | self.operations.extend; |
339 | self.values.extend; |
340 | self.settings.extend; |
341 | |
342 | |
343 | |
344 | |
345 | |
346 | |
347 | O: GiteratedObject + 'static, |
348 | D: + 'static, |
349 | S: GiteratedRuntimeState, |
350 | |
351 | |
352 | operation_name |
353 | |
354 | |
355 | |
356 | object_name |
357 | |
358 | |
359 | async |
360 | &self, |
361 | object: &O, |
362 | operation: D, |
363 | state: S, |
364 | operation_state: &StackOperationState, |
365 | |
366 | // Erase object and operation types. |
367 | let object = object as &dyn Any; |
368 | let operation = Box new as ; |
369 | |
370 | // We need to determine the type of the object, iterate through all known |
371 | // object types and check if the &dyn Any we have is the same type as the |
372 | // object type. |
373 | let object_type = |
374 | let mut object_type = None; |
375 | |
376 | for in self.metadata.objects.iter |
377 | if |
378 | object_type = Some; |
379 | break; |
380 | |
381 | |
382 | |
383 | object_type |
384 | |
385 | .ok_or_else?; |
386 | |
387 | // We need to hijack get_value, set_setting, and get_setting. |
388 | if operation. |
389 | todo! |
390 | else if operation. |
391 | todo! |
392 | else if operation. |
393 | todo! |
394 | |
395 | |
396 | // Resolve the operation from the known operations table. |
397 | let operation_type = |
398 | let mut operation_type = None; |
399 | |
400 | for in self.metadata.operations.iter |
401 | // Skip elements that we know will not match |
402 | if target.object_name != object_type |
403 | continue; |
404 | |
405 | |
406 | if |
407 | operation_type = Some; |
408 | break; |
409 | |
410 | |
411 | |
412 | operation_type |
413 | |
414 | .ok_or_else?; |
415 | |
416 | // Resolve the handler from our handler tree |
417 | let handler_tree = self |
418 | .operation_handlers |
419 | .get |
420 | .ok_or_else?; |
421 | |
422 | let raw_result = handler_tree.handle; |
423 | |
424 | // Convert the dynamic result back into its concrete type |
425 | match raw_result |
426 | Ok => Ok, |
427 | Err => Err |
428 | => Internal, | Internal
429 | => | Operation
430 | Operation |
431 | |
432 | => Unhandled, | Unhandled
433 | , |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | /// Handles a giterated network message, returning either a raw success |
440 | /// payload or a serialized error payload. |
441 | pub async |
442 | &self, |
443 | message: AuthenticatedPayload, |
444 | state: &S, |
445 | operation_state: &StackOperationState, |
446 | |
447 | let message: = message.into_message_v2; |
448 | |
449 | // Deserialize the object, also getting the object type's name |
450 | let = |
451 | let mut result = None; |
452 | |
453 | for in self.metadata.objects.iter |
454 | if let Ok = |
455 | result = Some; |
456 | break; |
457 | |
458 | |
459 | |
460 | result |
461 | |
462 | .ok_or_else?; |
463 | |
464 | let target = ObjectOperationPair |
465 | object_name: object_type, |
466 | operation_name: message.operation, |
467 | ; |
468 | |
469 | // Resolve the target operations from the handlers table |
470 | let handler = self |
471 | .operation_handlers |
472 | .get |
473 | .ok_or_else?; |
474 | |
475 | // Deserialize the operation |
476 | let meta = self |
477 | .metadata |
478 | .operations |
479 | .get |
480 | .ok_or_else?; |
481 | |
482 | let operation = |
483 | map_err?; | .
484 | |
485 | // Get the raw result of the operation, where the return values are boxed. |
486 | let raw_result = handler.handle; |
487 | |
488 | // Deserialize the raw result for the network |
489 | match raw_result |
490 | Ok => Ok |
491 | .map_err?, |
492 | Err => Err |
493 | => Operation | Operation
494 | |
495 | .map_err?, |
496 | , |
497 | => Internal, | Internal
498 | => Unhandled, | Unhandled
499 | , |
500 | |
501 | |
502 | |
503 |