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

ambee/giterated

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

Major refactor to handler traits

Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Squashed commit of the following: commit 62e1ecf76ee31cda0bab4602d9d00fa0dc2f9158 Author: Amber <[email protected]> Date: Wed Oct 11 09:31:11 2023 -0500 Update commit dfd2d1b0b5d81ee3bc48f0321c6aceaa677e3b8b Author: Amber <[email protected]> Date: Wed Oct 11 09:31:07 2023 -0500 Major refactor to handler traits Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Removed dead and legacy code. I think... commit 57b4b398eff32e69f2f4b9700e42a1277a4d1055 Author: Amber <[email protected]> Date: Sun Oct 1 23:05:10 2023 -0500 New handler trait for giterated stack Refactor the old handler trait so it is more generic and can be used for specific kinds of handlers

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90c4780

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