Unified stack `GetValue` implementation
parent: tbd commit: 325f5af
1 | use ; |
2 | |
3 | use FutureExt; |
4 | use |
5 | , | AuthenticatedPayload
6 | , |
7 | , | Instance
8 | , | GiteratedMessage
9 | |
10 | AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse, |
11 | , |
12 | , | ObjectBackend
13 | , |
14 | , |
15 | , |
16 | ; |
17 | use trace; |
18 | |
19 | use crate:: |
20 | GiteratedOperationHandler, ObjectMeta, ObjectOperationPair, ObjectValuePair, OperationMeta, |
21 | OperationWrapper, SettingMeta, StackOperationState, ValueMeta, |
22 | ; |
23 | |
24 | /// Temporary name for the next generation of Giterated stack |
25 | |
26 | |
27 | operation_handlers: , |
28 | value_getters: , |
29 | setting_getters: , |
30 | metadata: RuntimeMetadata, |
31 | |
32 | |
33 | |
34 | |
35 | &mut self, |
36 | builder: , |
37 | |
38 | for in builder.operation_handlers |
39 | let tree = self.get_or_create_tree; |
40 | |
41 | tree.push; |
42 | |
43 | |
44 | for in builder.value_getters |
45 | assert!; |
46 | |
47 | |
48 | for in builder.setting_getters |
49 | assert!; |
50 | |
51 | |
52 | self.metadata.append; |
53 | |
54 | self |
55 | |
56 | |
57 | |
58 | if self.operation_handlers.contains_key |
59 | self.operation_handlers.get_mut .unwrap |
60 | else |
61 | self.operation_handlers |
62 | .insert; |
63 | |
64 | self.operation_handlers.get_mut .unwrap |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | elements: , |
71 | |
72 | |
73 | |
74 | |
75 | Self |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | self.elements.push; |
82 | |
83 | |
84 | pub async |
85 | &self, |
86 | object: & , |
87 | operation: & , |
88 | operation_state: &StackOperationState, |
89 | |
90 | for handler in self.elements.iter |
91 | match handler.handle .await |
92 | Ok => return Ok, |
93 | Err => match err |
94 | => | Operation
95 | return Err |
96 | |
97 | => return Err, | Internal
98 | _ => |
99 | continue; |
100 | |
101 | , |
102 | |
103 | |
104 | |
105 | Err |
106 | |
107 | |
108 | |
109 | /// Stores runtime metadata for all in-use Giterated protocol types. |
110 | |
111 | |
112 | objects: , |
113 | operations: , |
114 | values: , |
115 | settings: , |
116 | |
117 | |
118 | /// Defines a type that is a valid Giterated runtime state. |
119 | /// |
120 | /// This allows for extraction of state in handlers, based on a |
121 | /// [`FromOperationState<S>`] impl on (what is in this case) [`Self`]. |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | operation_handlers: , |
128 | value_getters: , |
129 | setting_getters: , |
130 | metadata: RuntimeMetadata, |
131 | state: S, |
132 | |
133 | |
134 | |
135 | |
136 | Self |
137 | operation_handlers: Default default, |
138 | value_getters: Default default, |
139 | setting_getters: Default default, |
140 | metadata: Default default, |
141 | state, |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | /// Insert an operation handler into the runtime builder. |
148 | /// |
149 | /// # Type Registration |
150 | /// Inserting the handler will automatically, if required, register the operation type of the |
151 | /// handler. It will **not** register the object type automatically. |
152 | |
153 | |
154 | O: GiteratedObject + 'static, |
155 | D: + 'static + Clone, |
156 | H: + 'static + Clone + Send + Sync, |
157 | : Send + Sync, | Failure
158 | : Send + Sync, | Success
159 | |
160 | let object_name = handler.object_name .to_string; |
161 | let operation_name = handler.operation_name .to_string; |
162 | |
163 | let wrapped = new; |
164 | |
165 | let pair = ObjectOperationPair |
166 | object_name, |
167 | operation_name, |
168 | ; |
169 | |
170 | self.operation_handlers.insert; |
171 | |
172 | self.metadata.; |
173 | |
174 | self |
175 | |
176 | |
177 | /// Register a [`GiteratedObject`] type with the runtime. |
178 | /// |
179 | /// # Type Registration |
180 | /// This will register the provided object type. |
181 | |
182 | self.metadata.; |
183 | |
184 | // Insert handler so ObjectRequest is handled properly |
185 | let handler = move |_object: &Instance, |
186 | operation: ObjectRequest, |
187 | _state: S, |
188 | _operation_state: StackOperationState, |
189 | stack: | |
190 | async move |
191 | for in stack.metadata.objects.iter |
192 | if .is_ok |
193 | return Ok; |
194 | |
195 | |
196 | |
197 | Err |
198 | |
199 | .boxed_local |
200 | ; |
201 | |
202 | self.operation; |
203 | |
204 | self |
205 | |
206 | |
207 | /// Register a [`Setting`] type with the runtime. |
208 | /// |
209 | /// # Type Registration |
210 | /// This will register the provided setting type. |
211 | |
212 | self.metadata.; |
213 | |
214 | self |
215 | |
216 | |
217 | /// Register a [`GiteratedObjectValue<O>`] type with the runtime, providing |
218 | /// its associated handler for [`GetValue`]. |
219 | /// |
220 | /// # Type Registration |
221 | /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified |
222 | /// object type. It will **not** register the object type automatically. |
223 | |
224 | |
225 | O: GiteratedObject + 'static, |
226 | V: + 'static + Clone, |
227 | F: + Clone + 'static + Send + Sync, |
228 | |
229 | let object_name = handler.object_name .to_string; |
230 | let value_name = value_name .to_string; |
231 | |
232 | let wrapped = new; |
233 | |
234 | let handler_object_name = object_name.clone; |
235 | let handler_value_name = value_name.clone; |
236 | |
237 | // Insert handler so GetValue is handled properly |
238 | let _handler = move |object: &O, |
239 | operation: , |
240 | _state: S, |
241 | operation_state: StackOperationState, |
242 | stack: | |
243 | let stack = stack.clone; |
244 | let object_name = handler_object_name; |
245 | let value_name = handler_value_name; |
246 | let object = object.clone; |
247 | async move |
248 | for in stack.value_getters.iter |
249 | if target.object_kind != object_name |
250 | continue; |
251 | |
252 | |
253 | if target.value_kind != value_name |
254 | continue; |
255 | |
256 | |
257 | return match getter |
258 | .handle |
259 | &, |
260 | & |
261 | value_name: operation.value_name, |
262 | ty: Default default, |
263 | as , |
264 | &operation_state, |
265 | |
266 | .await |
267 | Ok => Ok, |
268 | Err => Err |
269 | => Operation, | Operation
270 | => Internal, | Internal
271 | => Unhandled, | Unhandled
272 | , |
273 | |
274 | |
275 | |
276 | Err |
277 | |
278 | .boxed_local |
279 | ; |
280 | |
281 | assert! |
282 | .value_getters |
283 | .insert |
284 | ObjectValuePair |
285 | object_kind: object_name, |
286 | value_kind: value_name |
287 | , |
288 | wrapped |
289 | |
290 | .is_none; |
291 | |
292 | self.metadata.; |
293 | |
294 | self |
295 | |
296 | |
297 | /// Register a handler for [`GetSetting`] for it's associated object type. |
298 | |
299 | |
300 | O: GiteratedObject + 'static, |
301 | F: + Clone + 'static + Send + Sync, |
302 | |
303 | let object_name = handler.object_name .to_string; |
304 | |
305 | let wrapped = new; |
306 | |
307 | assert!; |
308 | |
309 | self |
310 | |
311 | |
312 | |
313 | |
314 | |
315 | let object_name = object_name .to_string; |
316 | |
317 | let object_meta = ObjectMeta |
318 | name: object_name.clone, |
319 | from_str: Box new, |
320 | any_is_same: Box new, |
321 | ; |
322 | |
323 | if self.objects.insert .is_some |
324 | trace! |
325 | "Registration of object {} overwrote previous registration.", |
326 | object_name |
327 | ; |
328 | else |
329 | trace! |
330 | |
331 | |
332 | |
333 | |
334 | &mut self, |
335 | |
336 | let object_name = object_name .to_string; |
337 | let operation_name = operation_name .to_string; |
338 | |
339 | if self |
340 | .operations |
341 | .insert |
342 | ObjectOperationPair |
343 | object_name: object_name.clone, |
344 | operation_name: operation_name.clone, |
345 | , |
346 | OperationMeta |
347 | name: operation_name, |
348 | object_kind: object_name, |
349 | deserialize: Box new |
350 | Ok |
351 | as |
352 | , |
353 | any_is_same: Box new, |
354 | serialize_success: Box new |
355 | let to_serialize = any. .unwrap; |
356 | to_vec |
357 | , |
358 | serialize_error: Box new |
359 | let to_serialize = any. .unwrap; |
360 | to_vec |
361 | , |
362 | , |
363 | |
364 | .is_some |
365 | |
366 | trace! |
367 | "Registration of object operation {}<{}> overwrote previous registration.", |
368 | , | operation_name
369 | object_name |
370 | ; |
371 | else |
372 | trace! |
373 | "Registration of object operation {}<{}>.", |
374 | , | operation_name
375 | object_name |
376 | |
377 | |
378 | |
379 | |
380 | |
381 | O: GiteratedObject + 'static, |
382 | V: + 'static, |
383 | > |
384 | &mut self, |
385 | |
386 | let object_name = object_name .to_string; |
387 | let value_name = value_name .to_string; |
388 | let value_name_for_get = value_name .to_string; |
389 | |
390 | if self |
391 | .values |
392 | .insert |
393 | ObjectValuePair |
394 | object_kind: object_name.clone, |
395 | value_kind: value_name.clone, |
396 | , |
397 | ValueMeta |
398 | name: value_name.clone, |
399 | deserialize: Box new, |
400 | serialize: Box new |
401 | let value = value. .unwrap; |
402 | |
403 | Ok |
404 | , |
405 | typed_get: Box new |
406 | Box new |
407 | value_name: value_name_for_get.clone, |
408 | ty: Default default, |
409 | |
410 | , |
411 | is_get_value_typed: Box new, |
412 | , |
413 | |
414 | .is_some |
415 | |
416 | trace! |
417 | "Registration of value <{}>::{} overwrote previous registration.", |
418 | , | object_name
419 | value_name |
420 | ; |
421 | else |
422 | trace! |
423 | "Registration of value <{}>::{}.", |
424 | , | object_name
425 | value_name |
426 | ; |
427 | |
428 | |
429 | |
430 | |
431 | let setting_name = name .to_string; |
432 | |
433 | if self |
434 | .settings |
435 | .insert |
436 | setting_name.clone, |
437 | SettingMeta |
438 | name: setting_name, |
439 | deserialize: Box new, |
440 | , |
441 | |
442 | .is_some |
443 | |
444 | trace! |
445 | "Registration of setting {} overwrote previous registration.", |
446 | name |
447 | ; |
448 | else |
449 | trace!; |
450 | |
451 | |
452 | |
453 | |
454 | self.objects.extend; |
455 | self.operations.extend; |
456 | self.values.extend; |
457 | self.settings.extend; |
458 | |
459 | |
460 | |
461 | /// Handles a giterated network message, returning either a raw success |
462 | /// payload or a serialized error payload. |
463 | pub async |
464 | &self, |
465 | message: AuthenticatedPayload, |
466 | operation_state: &StackOperationState, |
467 | |
468 | let message: = message.into_message; |
469 | |
470 | // Deserialize the object, also getting the object type's name |
471 | let = |
472 | let mut result = None; |
473 | |
474 | for in self.metadata.objects.iter |
475 | if let Ok = |
476 | result = Some; |
477 | break; |
478 | |
479 | |
480 | |
481 | result |
482 | |
483 | .ok_or_else?; |
484 | |
485 | trace! |
486 | "Handling network message {}::<{}>", |
487 | message.operation, |
488 | object_type |
489 | ; |
490 | |
491 | if message.operation == "get_value" |
492 | // Special case |
493 | let operation: GetValue = from_slice .unwrap; |
494 | |
495 | return self |
496 | .network_get_value |
497 | .await; |
498 | |
499 | |
500 | let target = ObjectOperationPair |
501 | object_name: object_type.clone, |
502 | operation_name: message.operation.clone, |
503 | ; |
504 | |
505 | // Resolve the target operations from the handlers table |
506 | let handler = self |
507 | .operation_handlers |
508 | .get |
509 | .ok_or_else?; |
510 | |
511 | trace! |
512 | "Resolved operation handler for network message {}::<{}>", |
513 | message.operation, |
514 | object_type |
515 | ; |
516 | |
517 | // Deserialize the operation |
518 | let meta = self |
519 | .metadata |
520 | .operations |
521 | .get |
522 | .ok_or_else?; |
523 | |
524 | let operation = |
525 | .map_err?; |
526 | |
527 | trace! |
528 | "Deserialized operation for network message {}::<{}>", |
529 | message.operation, |
530 | object_type |
531 | ; |
532 | |
533 | trace! |
534 | "Calling handler for network message {}::<{}>", |
535 | message.operation, |
536 | object_type |
537 | ; |
538 | |
539 | // Get the raw result of the operation, where the return values are boxed. |
540 | let raw_result = handler.handle .await; |
541 | |
542 | trace! |
543 | "Finished handling network message {}::<{}>", |
544 | message.operation, |
545 | object_type |
546 | ; |
547 | |
548 | // Deserialize the raw result for the network |
549 | match raw_result |
550 | Ok => Ok |
551 | .map_err?, |
552 | Err => Err |
553 | => Operation | Operation
554 | |
555 | .map_err?, |
556 | , |
557 | => Internal, | Internal
558 | => Unhandled, | Unhandled
559 | , |
560 | |
561 | |
562 | |
563 | pub async |
564 | &self, |
565 | object: , |
566 | object_kind: String, |
567 | operation: GetValue, |
568 | operation_state: &StackOperationState, |
569 | |
570 | trace!; |
571 | |
572 | let value_meta = self |
573 | .metadata |
574 | .values |
575 | .get |
576 | object_kind: object_kind.clone, |
577 | value_kind: operation.value_name.clone, |
578 | |
579 | .ok_or_else?; |
580 | |
581 | for in self.value_getters.iter |
582 | if target.object_kind != object_kind |
583 | continue; |
584 | |
585 | |
586 | if target.value_kind != operation.value_name |
587 | continue; |
588 | |
589 | |
590 | return match getter |
591 | .handle |
592 | .await |
593 | |
594 | Ok => |
595 | // Serialize success, which is the value type itself |
596 | let serialized = |
597 | .map_err?; |
598 | |
599 | Ok |
600 | |
601 | Err => Err |
602 | => | Operation
603 | // Failure is sourced from GetValue operation, but this is hardcoded for now |
604 | let failure: GetValueError = *failure.downcast .unwrap; |
605 | |
606 | Operation |
607 | to_vec |
608 | .map_err?, |
609 | |
610 | |
611 | => Internal, | Internal
612 | => Unhandled, | Unhandled
613 | , |
614 | ; |
615 | |
616 | |
617 | Err |
618 | |
619 | |
620 | pub async |
621 | &self, |
622 | _operation: GetSetting, |
623 | _operation_state: &StackOperationState, |
624 | |
625 | todo! |
626 | |
627 | |
628 | pub async |
629 | &self, |
630 | _operation: SetSetting, |
631 | _operation_state: &StackOperationState, |
632 | |
633 | todo! |
634 | |
635 | |
636 | |
637 | use Debug; |
638 | |
639 | |
640 | |
641 | async |
642 | &self, |
643 | in_object: O, |
644 | operation_name: &str, |
645 | payload: D, |
646 | operation_state: &StackOperationState, |
647 | |
648 | |
649 | O: GiteratedObject + Debug + 'static, |
650 | D: + Debug + 'static, |
651 | |
652 | // Erase object and operation types. |
653 | let object = Box new as ; |
654 | let operation = Box new as ; |
655 | |
656 | // We need to determine the type of the object, iterate through all known |
657 | // object types and check if the &dyn Any we have is the same type as the |
658 | // object type. |
659 | let object_type = |
660 | let mut object_type = None; |
661 | |
662 | for in self.metadata.objects.iter |
663 | if |
664 | object_type = Some; |
665 | break; |
666 | |
667 | |
668 | |
669 | object_type |
670 | |
671 | .ok_or_else?; |
672 | |
673 | // We need to hijack get_value, set_setting, and get_setting. |
674 | if operation_name == "get_value" |
675 | let mut value_meta = None; |
676 | for in self.metadata.values.iter |
677 | if |
678 | value_meta = Some; |
679 | break; |
680 | |
681 | |
682 | |
683 | let value_meta = value_meta.ok_or_else?; |
684 | |
685 | let value_name = value_meta.name.clone; |
686 | |
687 | trace!; |
688 | |
689 | for in self.value_getters.iter |
690 | if target.object_kind != object_type |
691 | continue; |
692 | |
693 | |
694 | if target.value_kind != value_name |
695 | continue; |
696 | |
697 | |
698 | return match getter |
699 | .handle |
700 | .await |
701 | |
702 | Ok => Ok, |
703 | Err => Err |
704 | => | Operation
705 | Operation |
706 | |
707 | => Internal, | Internal
708 | => Unhandled, | Unhandled
709 | , |
710 | ; |
711 | |
712 | |
713 | return Err; |
714 | else if operation. |
715 | let get_setting: = operation.downcast .unwrap; |
716 | let setting_name = get_setting.setting_name.clone; |
717 | |
718 | // Get the setting getter for the object type |
719 | let getter = self |
720 | .setting_getters |
721 | .get |
722 | .ok_or_else?; |
723 | |
724 | let setting = getter |
725 | .handle |
726 | &, |
727 | &, |
728 | operation_state, |
729 | |
730 | .await |
731 | .map_err?; |
732 | |
733 | let _setting_meta = self |
734 | .metadata |
735 | .settings |
736 | .get |
737 | .ok_or_else?; |
738 | |
739 | let setting_success: Success = |
740 | *setting.downcast .unwrap; |
741 | |
742 | return Ok; |
743 | else if operation. |
744 | todo! |
745 | else if operation. |
746 | todo! |
747 | |
748 | |
749 | // Resolve the operation from the known operations table. |
750 | let operation_type = |
751 | let mut operation_type = None; |
752 | |
753 | for in self.metadata.operations.iter |
754 | // Skip elements that we know will not match |
755 | if target.object_name != object_type |
756 | continue; |
757 | |
758 | |
759 | if target.operation_name != operation_name |
760 | continue; |
761 | |
762 | |
763 | if |
764 | operation_type = Some; |
765 | break; |
766 | |
767 | |
768 | |
769 | operation_type |
770 | |
771 | .ok_or_else?; |
772 | |
773 | // Resolve the handler from our handler tree |
774 | let handler_tree = self |
775 | .operation_handlers |
776 | .get |
777 | .ok_or_else?; |
778 | |
779 | let raw_result = handler_tree |
780 | .handle |
781 | .await; |
782 | |
783 | // Convert the dynamic result back into its concrete type |
784 | match raw_result |
785 | Ok => Ok, |
786 | Err => Err |
787 | => Internal, | Internal
788 | => | Operation
789 | Operation |
790 | |
791 | => Unhandled, | Unhandled
792 | , |
793 | |
794 | |
795 | |
796 | async |
797 | &self, |
798 | object_str: &str, |
799 | _operation_state: &StackOperationState, |
800 | |
801 | // TODO: Authorization? |
802 | for in self.metadata.objects.iter |
803 | if let Ok = |
804 | return Ok |
805 | new_unchecked |
806 | ; |
807 | |
808 | |
809 | |
810 | Err |
811 | |
812 | |
813 |