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

ambee/giterated

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

Add support for networked GetSetting to Unified Stack refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨da6d78e

⁨giterated-stack/src/handler.rs⁩ - ⁨30051⁩ bytes
Raw
1 use std::{any::Any, collections::HashMap, sync::Arc};
2
3 use futures_util::FutureExt;
4 use giterated_models::{
5 authenticated::AuthenticatedPayload,
6 error::{GetValueError, OperationError},
7 instance::Instance,
8 message::GiteratedMessage,
9 object::{
10 AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse,
11 },
12 object_backend::ObjectBackend,
13 operation::{AnyOperation, GiteratedOperation},
14 settings::{GetSetting, GetSettingError, SetSetting, Setting},
15 value::{AnyValue, GetValue, GetValueTyped, GiteratedObjectValue},
16 };
17 use tracing::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 #[derive(Default)]
26 pub struct GiteratedStack {
27 operation_handlers: HashMap<ObjectOperationPair, HandlerTree>,
28 value_getters: HashMap<ObjectValuePair, OperationWrapper>,
29 setting_getters: HashMap<String, OperationWrapper>,
30 metadata: RuntimeMetadata,
31 }
32
33 impl GiteratedStack {
34 pub fn merge_builder<S: GiteratedStackState>(
35 &mut self,
36 builder: SubstackBuilder<S>,
37 ) -> &mut Self {
38 for (target, handler) in builder.operation_handlers {
39 let tree = self.get_or_create_tree(&target);
40
41 tree.push(handler);
42 }
43
44 for (target, handler) in builder.value_getters {
45 assert!(self.value_getters.insert(target, handler).is_none());
46 }
47
48 for (target, handler) in builder.setting_getters {
49 assert!(self.setting_getters.insert(target, handler).is_none());
50 }
51
52 self.metadata.append(builder.metadata);
53
54 self
55 }
56
57 fn get_or_create_tree(&mut self, target: &ObjectOperationPair) -> &mut HandlerTree {
58 if self.operation_handlers.contains_key(target) {
59 self.operation_handlers.get_mut(target).unwrap()
60 } else {
61 self.operation_handlers
62 .insert(target.clone(), HandlerTree::default());
63
64 self.operation_handlers.get_mut(target).unwrap()
65 }
66 }
67 }
68
69 pub struct HandlerTree {
70 elements: Vec<OperationWrapper>,
71 }
72
73 impl Default for HandlerTree {
74 fn default() -> Self {
75 Self { elements: vec![] }
76 }
77 }
78
79 impl HandlerTree {
80 pub fn push(&mut self, handler: OperationWrapper) {
81 self.elements.push(handler);
82 }
83
84 pub async fn handle(
85 &self,
86 object: &Box<dyn Any + Send + Sync>,
87 operation: &Box<dyn Any + Send + Sync>,
88 operation_state: &StackOperationState,
89 ) -> Result<Box<dyn Any + 'static>, OperationError<Box<dyn Any + 'static>>> {
90 for handler in self.elements.iter() {
91 match handler.handle(object, &operation, operation_state).await {
92 Ok(success) => return Ok(success),
93 Err(err) => match err {
94 OperationError::Operation(failure) => {
95 return Err(OperationError::Operation(failure))
96 }
97 OperationError::Internal(e) => return Err(OperationError::Internal(e)),
98 _ => {
99 continue;
100 }
101 },
102 }
103 }
104
105 Err(OperationError::Unhandled)
106 }
107 }
108
109 /// Stores runtime metadata for all in-use Giterated protocol types.
110 #[derive(Default)]
111 struct RuntimeMetadata {
112 objects: HashMap<String, ObjectMeta>,
113 operations: HashMap<ObjectOperationPair, OperationMeta>,
114 values: HashMap<ObjectValuePair, ValueMeta>,
115 settings: HashMap<String, SettingMeta>,
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 pub trait GiteratedStackState: Send + Sync + Clone {}
123
124 impl<T: Send + Sync + Clone> GiteratedStackState for T {}
125
126 pub struct SubstackBuilder<S: GiteratedStackState> {
127 operation_handlers: HashMap<ObjectOperationPair, OperationWrapper>,
128 value_getters: HashMap<ObjectValuePair, OperationWrapper>,
129 setting_getters: HashMap<String, OperationWrapper>,
130 metadata: RuntimeMetadata,
131 state: S,
132 }
133
134 impl<S: GiteratedStackState + 'static> SubstackBuilder<S> {
135 pub fn new(state: S) -> Self {
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 impl<S: GiteratedStackState + 'static> SubstackBuilder<S> {
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 pub fn operation<A, O, D, H>(&mut self, handler: H) -> &mut Self
153 where
154 O: GiteratedObject + 'static,
155 D: GiteratedOperation<O> + 'static + Clone,
156 H: GiteratedOperationHandler<A, O, D, S> + 'static + Clone + Send + Sync,
157 D::Failure: Send + Sync,
158 D::Success: Send + Sync,
159 {
160 let object_name = handler.object_name().to_string();
161 let operation_name = handler.operation_name().to_string();
162
163 let wrapped = OperationWrapper::new(handler, self.state.clone());
164
165 let pair = ObjectOperationPair {
166 object_name,
167 operation_name,
168 };
169
170 self.operation_handlers.insert(pair, wrapped);
171
172 self.metadata.register_operation::<O, D>();
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 pub fn object<O: GiteratedObject + 'static>(&mut self) -> &mut Self {
182 self.metadata.register_object::<O>();
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: Arc<GiteratedStack>| {
190 async move {
191 for (_object_name, object_meta) in stack.metadata.objects.iter() {
192 if (object_meta.from_str)(&operation.0).is_ok() {
193 return Ok(ObjectResponse(operation.0));
194 }
195 }
196
197 Err(OperationError::Unhandled)
198 }
199 .boxed_local()
200 };
201
202 self.operation(handler);
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 pub fn setting<T: Setting + 'static>(&mut self) -> &mut Self {
212 self.metadata.register_setting::<T>();
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 pub fn value<O, V, A, F>(&mut self, handler: F) -> &mut Self
224 where
225 O: GiteratedObject + 'static,
226 V: GiteratedObjectValue<Object = O> + 'static + Clone,
227 F: GiteratedOperationHandler<A, O, GetValueTyped<V>, S> + Clone + 'static + Send + Sync,
228 {
229 let object_name = handler.object_name().to_string();
230 let value_name = V::value_name().to_string();
231
232 let wrapped = OperationWrapper::new(handler, self.state.clone());
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: GetValueTyped<AnyValue<O>>,
240 _state: S,
241 operation_state: StackOperationState,
242 stack: Arc<GiteratedStack>| {
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 (target, getter) 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 &(Box::new(object.clone()) as Box<dyn Any + Send + Sync>),
260 &(Box::new(GetValueTyped::<V> {
261 value_name: operation.value_name,
262 ty: Default::default(),
263 }) as Box<dyn Any + Send + Sync>),
264 &operation_state,
265 )
266 .await {
267 Ok(success) => Ok(*success.downcast::<<GetValueTyped<V> as GiteratedOperation<O>>::Success>().unwrap()),
268 Err(err) => Err(match err {
269 OperationError::Operation(failure) => OperationError::Operation(*failure.downcast::<<GetValueTyped<V> as GiteratedOperation<O>>::Failure>().unwrap()),
270 OperationError::Internal(internal) => OperationError::Internal(internal),
271 OperationError::Unhandled => OperationError::Unhandled,
272 }),
273 }
274 }
275
276 Err(OperationError::Unhandled)
277 }
278 .boxed_local()
279 };
280
281 assert!(self
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.register_value::<O, V>();
293
294 self
295 }
296
297 /// Register a handler for [`GetSetting`] for it's associated object type.
298 pub fn object_settings<O, A, F>(&mut self, handler: F) -> &mut Self
299 where
300 O: GiteratedObject + 'static,
301 F: GiteratedOperationHandler<A, O, GetSetting, S> + Clone + 'static + Send + Sync,
302 {
303 let object_name = handler.object_name().to_string();
304
305 let wrapped = OperationWrapper::new(handler, self.state.clone());
306
307 assert!(self.setting_getters.insert(object_name, wrapped).is_none());
308
309 self
310 }
311 }
312
313 impl RuntimeMetadata {
314 fn register_object<O: GiteratedObject + 'static>(&mut self) {
315 let object_name = O::object_name().to_string();
316
317 let object_meta = ObjectMeta {
318 name: object_name.clone(),
319 from_str: Box::new(|str| Ok(Box::new(O::from_str(&str).map_err(|_| ())?))),
320 any_is_same: Box::new(|any| any.is::<O>()),
321 };
322
323 if self.objects.insert(object_name, object_meta).is_some() {
324 trace!(
325 "Registration of object {} overwrote previous registration.",
326 O::object_name()
327 );
328 } else {
329 trace!("Registration of object {}.", O::object_name())
330 }
331 }
332
333 fn register_operation<O: GiteratedObject + 'static, D: GiteratedOperation<O> + 'static>(
334 &mut self,
335 ) {
336 let object_name = O::object_name().to_string();
337 let operation_name = D::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(|bytes| {
350 Ok(Box::new(serde_json::from_slice::<D>(bytes)?)
351 as Box<dyn Any + Send + Sync>)
352 }),
353 any_is_same: Box::new(|any_box| any_box.is::<D>()),
354 serialize_success: Box::new(|any| {
355 let to_serialize = any.downcast::<D::Success>().unwrap();
356 serde_json::to_vec(&to_serialize)
357 }),
358 serialize_error: Box::new(|any| {
359 let to_serialize = any.downcast::<D::Failure>().unwrap();
360 serde_json::to_vec(&to_serialize)
361 }),
362 },
363 )
364 .is_some()
365 {
366 trace!(
367 "Registration of object operation {}<{}> overwrote previous registration.",
368 D::operation_name(),
369 O::object_name()
370 );
371 } else {
372 trace!(
373 "Registration of object operation {}<{}>.",
374 D::operation_name(),
375 O::object_name()
376 )
377 }
378 }
379
380 fn register_value<
381 O: GiteratedObject + 'static,
382 V: GiteratedObjectValue<Object = O> + 'static,
383 >(
384 &mut self,
385 ) {
386 let object_name = O::object_name().to_string();
387 let value_name = V::value_name().to_string();
388 let value_name_for_get = V::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(|bytes| Ok(Box::new(serde_json::from_slice(&bytes)?))),
400 serialize: Box::new(|value| {
401 let value = value.downcast::<V>().unwrap();
402
403 Ok(serde_json::to_vec(&*value)?)
404 }),
405 typed_get: Box::new(move || {
406 Box::new(GetValueTyped::<V> {
407 value_name: value_name_for_get.clone(),
408 ty: Default::default(),
409 })
410 }),
411 is_get_value_typed: Box::new(move |typed| typed.is::<GetValueTyped<V>>()),
412 },
413 )
414 .is_some()
415 {
416 trace!(
417 "Registration of value <{}>::{} overwrote previous registration.",
418 O::object_name(),
419 V::value_name()
420 );
421 } else {
422 trace!(
423 "Registration of value <{}>::{}.",
424 O::object_name(),
425 V::value_name()
426 );
427 }
428 }
429
430 fn register_setting<S: Setting + 'static>(&mut self) {
431 let setting_name = S::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(|bytes| Ok(Box::new(serde_json::from_slice(bytes)?))),
440 serialize: Box::new(|source| {
441 serde_json::to_value(source.downcast::<S>().unwrap())
442 }),
443 },
444 )
445 .is_some()
446 {
447 trace!(
448 "Registration of setting {} overwrote previous registration.",
449 S::name()
450 );
451 } else {
452 trace!("Registration of setting {}.", S::name());
453 }
454 }
455
456 fn append(&mut self, other: Self) {
457 self.objects.extend(other.objects);
458 self.operations.extend(other.operations);
459 self.values.extend(other.values);
460 self.settings.extend(other.settings);
461 }
462 }
463 impl GiteratedStack {
464 /// Handles a giterated network message, returning either a raw success
465 /// payload or a serialized error payload.
466 pub async fn handle_network_message(
467 &self,
468 message: AuthenticatedPayload,
469 operation_state: &StackOperationState,
470 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
471 let message: GiteratedMessage<AnyObject, AnyOperation> = message.into_message();
472
473 // Deserialize the object, also getting the object type's name
474 let (object_type, object) = {
475 let mut result = None;
476
477 for (object_type, object_meta) in self.metadata.objects.iter() {
478 if let Ok(object) = (object_meta.from_str)(&message.object.0) {
479 result = Some((object_type.clone(), object));
480 break;
481 }
482 }
483
484 result
485 }
486 .ok_or_else(|| OperationError::Unhandled)?;
487
488 trace!(
489 "Handling network message {}::<{}>",
490 message.operation,
491 object_type
492 );
493
494 if message.operation == "get_value" {
495 // Special case
496 let operation: GetValue = serde_json::from_slice(&message.payload.0).unwrap();
497
498 return self
499 .network_get_value(object, object_type.clone(), operation, operation_state)
500 .await;
501 }
502
503 let target = ObjectOperationPair {
504 object_name: object_type.clone(),
505 operation_name: message.operation.clone(),
506 };
507
508 // Resolve the target operations from the handlers table
509 let handler = self
510 .operation_handlers
511 .get(&target)
512 .ok_or_else(|| OperationError::Unhandled)?;
513
514 trace!(
515 "Resolved operation handler for network message {}::<{}>",
516 message.operation,
517 object_type
518 );
519
520 // Deserialize the operation
521 let meta = self
522 .metadata
523 .operations
524 .get(&target)
525 .ok_or_else(|| OperationError::Unhandled)?;
526
527 let operation = (meta.deserialize)(&message.payload.0)
528 .map_err(|e| OperationError::Internal(e.to_string()))?;
529
530 trace!(
531 "Deserialized operation for network message {}::<{}>",
532 message.operation,
533 object_type
534 );
535
536 trace!(
537 "Calling handler for network message {}::<{}>",
538 message.operation,
539 object_type
540 );
541
542 // Get the raw result of the operation, where the return values are boxed.
543 let raw_result = handler.handle(&object, &operation, operation_state).await;
544
545 trace!(
546 "Finished handling network message {}::<{}>",
547 message.operation,
548 object_type
549 );
550
551 // Deserialize the raw result for the network
552 match raw_result {
553 Ok(success) => Ok((meta.serialize_success)(success)
554 .map_err(|e| OperationError::Internal(e.to_string()))?),
555 Err(err) => Err(match err {
556 OperationError::Operation(failure) => OperationError::Operation(
557 (meta.serialize_error)(failure)
558 .map_err(|e| OperationError::Internal(e.to_string()))?,
559 ),
560 OperationError::Internal(internal) => OperationError::Internal(internal),
561 OperationError::Unhandled => OperationError::Unhandled,
562 }),
563 }
564 }
565
566 pub async fn network_get_value(
567 &self,
568 object: Box<dyn Any + Send + Sync>,
569 object_kind: String,
570 operation: GetValue,
571 operation_state: &StackOperationState,
572 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
573 trace!("Handling network get_value for {}", operation.value_name);
574
575 let value_meta = self
576 .metadata
577 .values
578 .get(&ObjectValuePair {
579 object_kind: object_kind.clone(),
580 value_kind: operation.value_name.clone(),
581 })
582 .ok_or_else(|| OperationError::Unhandled)?;
583
584 for (target, getter) in self.value_getters.iter() {
585 if target.object_kind != object_kind {
586 continue;
587 }
588
589 if target.value_kind != operation.value_name {
590 continue;
591 }
592
593 return match getter
594 .handle(&(object), &((value_meta.typed_get)()), &operation_state)
595 .await
596 {
597 Ok(success) => {
598 // Serialize success, which is the value type itself
599 let serialized = (value_meta.serialize)(success)
600 .map_err(|e| OperationError::Internal(e.to_string()))?;
601
602 Ok(serialized)
603 }
604 Err(err) => Err(match err {
605 OperationError::Operation(failure) => {
606 // Failure is sourced from GetValue operation, but this is hardcoded for now
607 let failure: GetValueError = *failure.downcast().unwrap();
608
609 OperationError::Operation(
610 serde_json::to_vec(&failure)
611 .map_err(|e| OperationError::Internal(e.to_string()))?,
612 )
613 }
614 OperationError::Internal(internal) => OperationError::Internal(internal),
615 OperationError::Unhandled => OperationError::Unhandled,
616 }),
617 };
618 }
619
620 Err(OperationError::Unhandled)
621 }
622
623 pub async fn network_get_setting(
624 &self,
625 object: Box<dyn Any + Send + Sync>,
626 object_kind: String,
627 operation: GetSetting,
628 operation_state: &StackOperationState,
629 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
630 trace!(
631 "Handling network {}::get_setting for {}",
632 object_kind,
633 operation.setting_name
634 );
635
636 let setting_meta = self
637 .metadata
638 .settings
639 .get(&object_kind)
640 .ok_or_else(|| OperationError::Unhandled)?;
641
642 let setting_getter = self
643 .setting_getters
644 .get(&object_kind)
645 .ok_or_else(|| OperationError::Unhandled)?;
646
647 let raw_result = setting_getter
648 .handle(&object, &(Box::new(operation) as Box<_>), operation_state)
649 .await;
650
651 match raw_result {
652 Ok(setting) => {
653 // We need to serialize this to Value
654 let value = (setting_meta.serialize)(setting).unwrap();
655
656 Ok(serde_json::to_vec(&value).unwrap())
657 }
658 Err(err) => Err(match err {
659 OperationError::Operation(failure) => {
660 // This will get GetSettingError
661 let error: GetSettingError = *failure.downcast().unwrap();
662
663 OperationError::Operation(serde_json::to_vec(&error).unwrap())
664 }
665 OperationError::Internal(internal) => OperationError::Internal(internal),
666 OperationError::Unhandled => OperationError::Unhandled,
667 }),
668 }
669 }
670
671 pub async fn network_set_setting(
672 &self,
673 _operation: SetSetting,
674 _operation_state: &StackOperationState,
675 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
676 todo!()
677 }
678 }
679
680 use core::fmt::Debug;
681
682 #[async_trait::async_trait(?Send)]
683 impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
684 async fn object_operation<O, D>(
685 &self,
686 in_object: O,
687 operation_name: &str,
688 payload: D,
689 operation_state: &StackOperationState,
690 ) -> Result<D::Success, OperationError<D::Failure>>
691 where
692 O: GiteratedObject + Debug + 'static,
693 D: GiteratedOperation<O> + Debug + 'static,
694 {
695 // Erase object and operation types.
696 let object = Box::new(in_object.clone()) as Box<dyn Any + Send + Sync>;
697 let operation = Box::new(payload) as Box<dyn Any + Send + Sync>;
698
699 // We need to determine the type of the object, iterate through all known
700 // object types and check if the &dyn Any we have is the same type as the
701 // object type.
702 let object_type = {
703 let mut object_type = None;
704
705 for (object_name, object_meta) in self.metadata.objects.iter() {
706 if (object_meta.any_is_same)(&in_object) {
707 object_type = Some(object_name.clone());
708 break;
709 }
710 }
711
712 object_type
713 }
714 .ok_or_else(|| OperationError::Unhandled)?;
715
716 // We need to hijack get_value, set_setting, and get_setting.
717 if operation_name == "get_value" {
718 let mut value_meta = None;
719 for (_, meta) in self.metadata.values.iter() {
720 if (meta.is_get_value_typed)(&operation) {
721 value_meta = Some(meta);
722 break;
723 }
724 }
725
726 let value_meta = value_meta.ok_or_else(|| OperationError::Unhandled)?;
727
728 let value_name = value_meta.name.clone();
729
730 trace!("Handling get_value for {}::{}", object_type, value_name);
731
732 for (target, getter) in self.value_getters.iter() {
733 if target.object_kind != object_type {
734 continue;
735 }
736
737 if target.value_kind != value_name {
738 continue;
739 }
740
741 return match getter
742 .handle(&(object), &((value_meta.typed_get)()), &operation_state)
743 .await
744 {
745 Ok(success) => Ok(*success.downcast().unwrap()),
746 Err(err) => Err(match err {
747 OperationError::Operation(failure) => {
748 OperationError::Operation(*failure.downcast::<D::Failure>().unwrap())
749 }
750 OperationError::Internal(internal) => OperationError::Internal(internal),
751 OperationError::Unhandled => OperationError::Unhandled,
752 }),
753 };
754 }
755
756 return Err(OperationError::Unhandled);
757 } else if operation.is::<GetSetting>() {
758 let get_setting: Box<GetSetting> = operation.downcast().unwrap();
759 let setting_name = get_setting.setting_name.clone();
760
761 // Get the setting getter for the object type
762 let getter = self
763 .setting_getters
764 .get(&object_type)
765 .ok_or_else(|| OperationError::Unhandled)?;
766
767 let setting = getter
768 .handle(
769 &(Box::new(in_object.clone()) as _),
770 &(Box::new(get_setting) as _),
771 operation_state,
772 )
773 .await
774 .map_err(|_e| OperationError::Unhandled)?;
775
776 let _setting_meta = self
777 .metadata
778 .settings
779 .get(&setting_name)
780 .ok_or_else(|| OperationError::Unhandled)?;
781
782 let setting_success: <D as GiteratedOperation<O>>::Success =
783 *setting.downcast().unwrap();
784
785 return Ok(setting_success);
786 } else if operation.is::<SetSetting>() {
787 todo!()
788 } else if operation.is::<ObjectRequest>() {
789 todo!()
790 }
791
792 // Resolve the operation from the known operations table.
793 let operation_type = {
794 let mut operation_type = None;
795
796 for (target, operation_meta) in self.metadata.operations.iter() {
797 // Skip elements that we know will not match
798 if target.object_name != object_type {
799 continue;
800 }
801
802 if target.operation_name != operation_name {
803 continue;
804 }
805
806 if (operation_meta.any_is_same)(&operation) {
807 operation_type = Some(target.clone());
808 break;
809 }
810 }
811
812 operation_type
813 }
814 .ok_or_else(|| OperationError::Unhandled)?;
815
816 // Resolve the handler from our handler tree
817 let handler_tree = self
818 .operation_handlers
819 .get(&operation_type)
820 .ok_or_else(|| OperationError::Unhandled)?;
821
822 let raw_result = handler_tree
823 .handle(&object, &operation, operation_state)
824 .await;
825
826 // Convert the dynamic result back into its concrete type
827 match raw_result {
828 Ok(result) => Ok(*result.downcast::<D::Success>().unwrap()),
829 Err(err) => Err(match err {
830 OperationError::Internal(internal) => OperationError::Internal(internal),
831 OperationError::Operation(boxed_error) => {
832 OperationError::Operation(*boxed_error.downcast::<D::Failure>().unwrap())
833 }
834 OperationError::Unhandled => OperationError::Unhandled,
835 }),
836 }
837 }
838
839 async fn get_object<O: GiteratedObject + Debug + 'static>(
840 &self,
841 object_str: &str,
842 _operation_state: &StackOperationState,
843 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
844 // TODO: Authorization?
845 for (_object_name, object_meta) in self.metadata.objects.iter() {
846 if let Ok(object) = (object_meta.from_str)(object_str) {
847 return Ok(unsafe {
848 Object::new_unchecked(*object.downcast::<O>().unwrap(), self.clone())
849 });
850 }
851 }
852
853 Err(OperationError::Unhandled)
854 }
855 }
856