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

ambee/giterated

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

Unified stack `GetValue` implementation

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨325f5af

⁨giterated-stack/src/handler.rs⁩ - ⁨28436⁩ 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, 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>(&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>(&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 },
441 )
442 .is_some()
443 {
444 trace!(
445 "Registration of setting {} overwrote previous registration.",
446 S::name()
447 );
448 } else {
449 trace!("Registration of setting {}.", S::name());
450 }
451 }
452
453 fn append(&mut self, other: Self) {
454 self.objects.extend(other.objects);
455 self.operations.extend(other.operations);
456 self.values.extend(other.values);
457 self.settings.extend(other.settings);
458 }
459 }
460 impl GiteratedStack {
461 /// Handles a giterated network message, returning either a raw success
462 /// payload or a serialized error payload.
463 pub async fn handle_network_message(
464 &self,
465 message: AuthenticatedPayload,
466 operation_state: &StackOperationState,
467 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
468 let message: GiteratedMessage<AnyObject, AnyOperation> = message.into_message();
469
470 // Deserialize the object, also getting the object type's name
471 let (object_type, object) = {
472 let mut result = None;
473
474 for (object_type, object_meta) in self.metadata.objects.iter() {
475 if let Ok(object) = (object_meta.from_str)(&message.object.0) {
476 result = Some((object_type.clone(), object));
477 break;
478 }
479 }
480
481 result
482 }
483 .ok_or_else(|| OperationError::Unhandled)?;
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 = serde_json::from_slice(&message.payload.0).unwrap();
494
495 return self
496 .network_get_value(object, object_type.clone(), operation, operation_state)
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(&target)
509 .ok_or_else(|| OperationError::Unhandled)?;
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(&target)
522 .ok_or_else(|| OperationError::Unhandled)?;
523
524 let operation = (meta.deserialize)(&message.payload.0)
525 .map_err(|e| OperationError::Internal(e.to_string()))?;
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(&object, &operation, operation_state).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(success) => Ok((meta.serialize_success)(success)
551 .map_err(|e| OperationError::Internal(e.to_string()))?),
552 Err(err) => Err(match err {
553 OperationError::Operation(failure) => OperationError::Operation(
554 (meta.serialize_error)(failure)
555 .map_err(|e| OperationError::Internal(e.to_string()))?,
556 ),
557 OperationError::Internal(internal) => OperationError::Internal(internal),
558 OperationError::Unhandled => OperationError::Unhandled,
559 }),
560 }
561 }
562
563 pub async fn network_get_value(
564 &self,
565 object: Box<dyn Any + Send + Sync>,
566 object_kind: String,
567 operation: GetValue,
568 operation_state: &StackOperationState,
569 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
570 trace!("Handling network get_value for {}", operation.value_name);
571
572 let value_meta = self
573 .metadata
574 .values
575 .get(&ObjectValuePair {
576 object_kind: object_kind.clone(),
577 value_kind: operation.value_name.clone(),
578 })
579 .ok_or_else(|| OperationError::Unhandled)?;
580
581 for (target, getter) 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(&(object), &((value_meta.typed_get)()), &operation_state)
592 .await
593 {
594 Ok(success) => {
595 // Serialize success, which is the value type itself
596 let serialized = (value_meta.serialize)(success)
597 .map_err(|e| OperationError::Internal(e.to_string()))?;
598
599 Ok(serialized)
600 }
601 Err(err) => Err(match err {
602 OperationError::Operation(failure) => {
603 // Failure is sourced from GetValue operation, but this is hardcoded for now
604 let failure: GetValueError = *failure.downcast().unwrap();
605
606 OperationError::Operation(
607 serde_json::to_vec(&failure)
608 .map_err(|e| OperationError::Internal(e.to_string()))?,
609 )
610 }
611 OperationError::Internal(internal) => OperationError::Internal(internal),
612 OperationError::Unhandled => OperationError::Unhandled,
613 }),
614 };
615 }
616
617 Err(OperationError::Unhandled)
618 }
619
620 pub async fn network_get_setting(
621 &self,
622 _operation: GetSetting,
623 _operation_state: &StackOperationState,
624 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
625 todo!()
626 }
627
628 pub async fn network_set_setting(
629 &self,
630 _operation: SetSetting,
631 _operation_state: &StackOperationState,
632 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
633 todo!()
634 }
635 }
636
637 use core::fmt::Debug;
638
639 #[async_trait::async_trait(?Send)]
640 impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
641 async fn object_operation<O, D>(
642 &self,
643 in_object: O,
644 operation_name: &str,
645 payload: D,
646 operation_state: &StackOperationState,
647 ) -> Result<D::Success, OperationError<D::Failure>>
648 where
649 O: GiteratedObject + Debug + 'static,
650 D: GiteratedOperation<O> + Debug + 'static,
651 {
652 // Erase object and operation types.
653 let object = Box::new(in_object.clone()) as Box<dyn Any + Send + Sync>;
654 let operation = Box::new(payload) as Box<dyn Any + Send + Sync>;
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 (object_name, object_meta) in self.metadata.objects.iter() {
663 if (object_meta.any_is_same)(&in_object) {
664 object_type = Some(object_name.clone());
665 break;
666 }
667 }
668
669 object_type
670 }
671 .ok_or_else(|| OperationError::Unhandled)?;
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) {
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!("Handling get_value for {}::{}", object_type, value_name);
688
689 for (target, getter) 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(&(object), &((value_meta.typed_get)()), &operation_state)
700 .await
701 {
702 Ok(success) => Ok(*success.downcast().unwrap()),
703 Err(err) => Err(match err {
704 OperationError::Operation(failure) => {
705 OperationError::Operation(*failure.downcast::<D::Failure>().unwrap())
706 }
707 OperationError::Internal(internal) => OperationError::Internal(internal),
708 OperationError::Unhandled => OperationError::Unhandled,
709 }),
710 };
711 }
712
713 return Err(OperationError::Unhandled);
714 } else if operation.is::<GetSetting>() {
715 let get_setting: Box<GetSetting> = 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(&object_type)
722 .ok_or_else(|| OperationError::Unhandled)?;
723
724 let setting = getter
725 .handle(
726 &(Box::new(in_object.clone()) as _),
727 &(Box::new(get_setting) as _),
728 operation_state,
729 )
730 .await
731 .map_err(|_e| OperationError::Unhandled)?;
732
733 let _setting_meta = self
734 .metadata
735 .settings
736 .get(&setting_name)
737 .ok_or_else(|| OperationError::Unhandled)?;
738
739 let setting_success: <D as GiteratedOperation<O>>::Success =
740 *setting.downcast().unwrap();
741
742 return Ok(setting_success);
743 } else if operation.is::<SetSetting>() {
744 todo!()
745 } else if operation.is::<ObjectRequest>() {
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 (target, operation_meta) 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 (operation_meta.any_is_same)(&operation) {
764 operation_type = Some(target.clone());
765 break;
766 }
767 }
768
769 operation_type
770 }
771 .ok_or_else(|| OperationError::Unhandled)?;
772
773 // Resolve the handler from our handler tree
774 let handler_tree = self
775 .operation_handlers
776 .get(&operation_type)
777 .ok_or_else(|| OperationError::Unhandled)?;
778
779 let raw_result = handler_tree
780 .handle(&object, &operation, operation_state)
781 .await;
782
783 // Convert the dynamic result back into its concrete type
784 match raw_result {
785 Ok(result) => Ok(*result.downcast::<D::Success>().unwrap()),
786 Err(err) => Err(match err {
787 OperationError::Internal(internal) => OperationError::Internal(internal),
788 OperationError::Operation(boxed_error) => {
789 OperationError::Operation(*boxed_error.downcast::<D::Failure>().unwrap())
790 }
791 OperationError::Unhandled => OperationError::Unhandled,
792 }),
793 }
794 }
795
796 async fn get_object<O: GiteratedObject + Debug + 'static>(
797 &self,
798 object_str: &str,
799 _operation_state: &StackOperationState,
800 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
801 // TODO: Authorization?
802 for (_object_name, object_meta) in self.metadata.objects.iter() {
803 if let Ok(object) = (object_meta.from_str)(object_str) {
804 return Ok(unsafe {
805 Object::new_unchecked(*object.downcast::<O>().unwrap(), self.clone())
806 });
807 }
808 }
809
810 Err(OperationError::Unhandled)
811 }
812 }
813