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

ambee/giterated

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

Re-expose Operation State in generics.

This is the worst code I have ever written. I hate the way this changes everything. ugh.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90db3e2

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