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

ambee/giterated

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

Merge branch dyn_inherent into master

This is a squashed commit of the following: commit 6b7c04bc1aae470d9c95b9c5f4e5698bd8c8fef0 Author: Amber <[email protected]> Date: Tue Sep 26 14:03:52 2023 -0500 Give meta types better ergonomics and location

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨f94279e

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