use std::any::Any; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::Deref; use std::str::FromStr; use std::{collections::HashMap, sync::Arc}; use anyhow::Error; use giterated_models::error::IntoInternalError; use giterated_models::instance::Instance; use giterated_models::object::ObjectResponse; use giterated_models::settings::{SetSettingError, Setting}; use giterated_models::value::GetValue; use giterated_models::{ error::OperationError, object::{GiteratedObject, Object, ObjectRequest, ObjectRequestError}, object_backend::ObjectBackend, operation::GiteratedOperation, settings::{GetSetting, SetSetting}, }; use tracing::{trace, warn}; use crate::handler::HandlerTree; use crate::provider::MetadataProvider; use crate::{ AnyFailure, AnyObject, AnyOperation, AnySetting, AnySuccess, AnyValue, HandlerResolvable, HandlerWrapper, MissingValue, ObjectOperationPair, ObjectSettingPair, ObjectValuePair, RuntimeMetadata, StackOperationState, SubstackBuilder, }; pub type OperationHandler = HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure, OS>; pub type ValueGetter = HandlerWrapper<(AnyObject, String), AnyValue, AnyFailure, OS>; pub type SettingGetter = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure, OS>; pub type ValueChange = HandlerWrapper<(AnyObject, AnyValue), (), anyhow::Error, OS>; pub type SettingChange = HandlerWrapper<(AnyObject, AnySetting), (), anyhow::Error, OS>; #[derive(Default, Clone)] pub struct GiteratedStack { pub inner: Arc>, } impl Deref for GiteratedStack { type Target = GiteratedStackInner; fn deref(&self) -> &Self::Target { &self.inner } } pub struct GiteratedStackInner { operation_handlers: HashMap, HandlerTree>>, value_getters: HashMap, ValueGetter>, setting_getters: HashMap<&'static str, SettingGetter>, value_change: HashMap, ValueChange>, setting_change: HashMap, SettingChange>, metadata_providers: Vec>, pub metadata: RuntimeMetadata, _marker: PhantomData, } impl Default for GiteratedStackInner { fn default() -> Self { Self { operation_handlers: Default::default(), value_getters: Default::default(), setting_getters: Default::default(), value_change: Default::default(), setting_change: Default::default(), metadata_providers: Default::default(), metadata: Default::default(), _marker: Default::default(), } } } impl Debug for GiteratedStack { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("GiteratedStack").finish() } } pub struct GiteratedStackBuilder { inner: GiteratedStackInner, } impl Default for GiteratedStackBuilder where GiteratedStack: HandlerResolvable<(Instance, ObjectRequest), OS>, as HandlerResolvable<(Instance, ObjectRequest), OS>>::Error: Into, { fn default() -> Self { let mut stack = Self { inner: Default::default(), }; #[derive(Clone)] struct InstanceResolver; let mut builder: SubstackBuilder = SubstackBuilder::new(InstanceResolver); builder.object::(); stack.merge_builder(builder); stack } } impl GiteratedStackBuilder { pub fn merge_builder( &mut self, mut builder: SubstackBuilder, ) -> &mut Self { for (target, handler) in builder.operation_handlers { let tree = self.get_or_create_tree(&target); tree.push(handler); } for (target, handler) in builder.value_getters { assert!(self.inner.value_getters.insert(target, handler).is_none()); } for (target, handler) in builder.setting_getters { assert!(self.inner.setting_getters.insert(target, handler).is_none()); } for (target, handler) in builder.value_change { self.inner.value_change.insert(target, handler); } for (target, handler) in builder.setting_change { self.inner.setting_change.insert(target, handler); } self.inner .metadata_providers .append(&mut builder.metadata_providers); self.inner.metadata.append(builder.metadata); self } fn get_or_create_tree( &mut self, target: &ObjectOperationPair<'static>, ) -> &mut HandlerTree> { if self.inner.operation_handlers.contains_key(target) { self.inner.operation_handlers.get_mut(target).unwrap() } else { self.inner .operation_handlers .insert(target.clone(), HandlerTree::default()); self.inner.operation_handlers.get_mut(target).unwrap() } } pub fn finish(self) -> GiteratedStack { GiteratedStack { inner: Arc::new(self.inner), } } } impl GiteratedStack { pub async fn value_update(&self, object: O, new_value: AnyValue, operation_state: &OS) where O: GiteratedObject + 'static, { trace!( "value updated {}::{}", O::object_name(), new_value.kind().value_kind ); let object = AnyObject::new(object); // First, resolve a handler for the exact object value pair if let Some(handler) = self.inner.value_change.get(&new_value.kind()) { // TODO let _ = handler .handle((object.clone(), new_value.clone()), operation_state.clone()) .await; } // We need to resolve for `any` object and `any` value combination let target = ObjectValuePair { object_kind: "any", value_kind: new_value.kind().value_kind, }; if let Some(handler) = self.inner.value_change.get(&target) { // TODO let _ = handler .handle((object.clone(), new_value.clone()), operation_state.clone()) .await; } let target = ObjectValuePair { object_kind: O::object_name(), value_kind: "any", }; if let Some(handler) = self.inner.value_change.get(&target) { // TODO let _ = handler .handle((object.clone(), new_value.clone()), operation_state.clone()) .await; } // Now resolve for both `any` let target = ObjectValuePair { object_kind: "any", value_kind: "any", }; if let Some(handler) = self.inner.value_change.get(&target) { // TODO let _ = handler .handle((object.clone(), new_value.clone()), operation_state.clone()) .await; } } pub async fn setting_update(&self, object: O, new_setting: S, operation_state: &OS) where O: GiteratedObject + 'static, S: Setting + 'static, { trace!("setting updated {}::{}", O::object_name(), S::name()); let target = ObjectSettingPair::from_types::(); if let Some(handler) = self.inner.setting_change.get(&target) { let _ = handler .handle( (AnyObject::new(object), AnySetting::new::(new_setting)), operation_state.clone(), ) .await; } } pub async fn new_object(&self, _new_object: &O, _operation_state: &StackOperationState) where O: GiteratedObject, { // TODO } /// Writes a setting for the specified object. pub async fn write_setting( &self, object: &O, setting: S, ) -> Result<(), OperationError<()>> where O: GiteratedObject + 'static + Clone, S: Setting + 'static + Clone, { for provider in self.inner.metadata_providers.iter() { if provider.provides_for(object as &dyn Any) { let setting_meta = self .inner .metadata .settings .get(&ObjectSettingPair::from_types::()) .ok_or_else(|| OperationError::Unhandled)?; let object_meta = self .inner .metadata .objects .get(O::object_name()) .ok_or_else(|| OperationError::Unhandled)?; let result = provider .write( AnyObject::new(object.clone()), object_meta, AnySetting::new::(setting), setting_meta, ) .await .as_internal_error_with_context(format!("writing setting {}", S::name())); return result; } } Err(OperationError::Unhandled) } /// Gets a setting for the specified object. pub async fn new_get_setting(&self, object: &O) -> Result> where O: GiteratedObject + 'static + Clone, S: Setting + 'static, { for provider in self.inner.metadata_providers.iter() { if provider.provides_for(object as &dyn Any) { trace!( "Resolving setting {} for object {} from provider.", S::name(), O::object_name() ); let setting_meta = self .inner .metadata .settings .get(&ObjectSettingPair::from_types::()) .ok_or_else(|| OperationError::Unhandled)?; let object_meta = self .inner .metadata .objects .get(O::object_name()) .ok_or_else(|| OperationError::Unhandled)?; let value = provider .read(AnyObject::new(object.clone()), object_meta, setting_meta) .await .as_internal_error_with_context(format!("getting setting {}", S::name()))?; return serde_json::from_value(value) .as_internal_error_with_context("deserializing setting"); } } trace!( "No provider registered for setting {} and object {}", S::name(), O::object_name() ); Err(OperationError::Unhandled) } } impl GiteratedStack { pub async fn get_setting( &self, object: AnyObject, object_kind: String, operation: GetSetting, _operation_state: &OS, ) -> Result>> { trace!( "Handling network {}::get_setting for {}", object_kind, operation.setting_name ); for provider in self.inner.metadata_providers.iter() { if provider.provides_for(object.deref()) { let setting_meta = self .inner .metadata .settings .get(&ObjectSettingPair { object_kind: &object_kind, setting_name: &operation.setting_name, }) .ok_or_else(|| OperationError::Unhandled)?; let object_meta = self .inner .metadata .objects .get(&object_kind) .ok_or_else(|| OperationError::Unhandled)?; let result = provider .read(object.clone(), object_meta, setting_meta) .await .as_internal_error_with_context(format!( "reading setting {}", operation.setting_name ))?; return (setting_meta.deserialize)(result).as_internal_error_with_context(format!( "deserializing setting {}", operation.setting_name )); } } trace!("setting {} doesn't exist", operation.setting_name); Err(OperationError::Unhandled) } } #[async_trait::async_trait(?Send)] impl ObjectBackend for GiteratedStack { async fn object_operation( &self, in_object: O, _operation_name: &str, payload: D, operation_state: &OS, ) -> Result> where O: GiteratedObject + Debug + 'static, D: GiteratedOperation + Debug + 'static, D::Success: Clone, D::Failure: Clone, { trace!( "Object operation for {}::{}", O::object_name(), D::operation_name() ); // Erase object and operation types. let object = AnyObject::new(in_object.clone()); let operation = AnyOperation::new(payload); let raw_result = self .new_operation_func(object, operation, operation_state.clone()) .await; // Convert the dynamic result back into its concrete type match raw_result { Ok(result) => Ok(result.0.downcast_ref::().unwrap().clone()), Err(err) => Err(match err { OperationError::Internal(internal) => { OperationError::Internal(internal.context(format!( "operation {}::{} handler outcome", O::object_name(), D::operation_name() ))) } OperationError::Operation(boxed_error) => OperationError::Operation( boxed_error.0.downcast_ref::().unwrap().clone(), ), OperationError::Unhandled => OperationError::Unhandled, }), } } async fn get_object( &self, object_str: &str, operation_state: &OS, ) -> Result, OperationError> where O: GiteratedObject + Debug + 'static, { // TODO: Authorization? for (object_name, object_meta) in self.inner.metadata.objects.iter() { if object_name != O::object_name() { continue; } if let Ok(object) = (object_meta.from_str)(object_str) { return Ok(unsafe { Object::new_unchecked(object.downcast_ref::().unwrap().clone(), self.clone()) }); } } if let Some(handler) = self.operation_handlers.get(&ObjectOperationPair { object_name: "any", operation_name: "any", }) { let result = handler .handle( ( AnyObject::new(Instance::from_str("giterated.dev").unwrap()), AnyOperation::new(ObjectRequest(object_str.to_string())), ), operation_state.clone(), ) .await; match result { Ok(success) => { let object: &ObjectResponse = success.0.downcast_ref().unwrap(); return Ok(unsafe { Object::new_unchecked(O::from_object_str(&object.0).unwrap(), self.clone()) }); } Err(err) => match err { OperationError::Operation(failure) => { let failure: &ObjectRequestError = failure.0.downcast_ref().unwrap(); return Err(OperationError::Operation(failure.clone())); } OperationError::Internal(internal) => { return Err(OperationError::Internal(internal)) } OperationError::Unhandled => {} }, }; } Err(OperationError::Unhandled) } } // Placeholder impl GiteratedStack { pub async fn new_operation_func( &self, object: AnyObject, operation: AnyOperation, operation_state: OS, ) -> Result> { let operation_name = operation.kind().operation_name; if let Some(handler_tree) = self.inner.operation_handlers.get(&ObjectOperationPair { object_name: "any", operation_name: "any", }) { match handler_tree .handle((object.clone(), operation.clone()), operation_state.clone()) .await { Ok(success) => return Ok(success), Err(err) => match err { OperationError::Operation(operation) => { return Err(OperationError::Operation(operation)) } OperationError::Internal(internal) => { return Err(OperationError::Internal(internal)) } OperationError::Unhandled => {} }, } } // We need to hijack get_value, set_setting, and get_setting. if operation_name == "get_value" { let get_value = operation .downcast_ref::() .ok_or_else(|| OperationError::Unhandled)?; let value_meta = self .inner .metadata .values .get(&ObjectValuePair { object_kind: object.kind(), value_kind: &get_value.value_name, }) .ok_or_else(|| OperationError::Unhandled)?; let value_name = value_meta.name.clone(); trace!("Handling get_value for {}::{}", object.kind(), value_name); if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair { object_kind: "any", value_kind: &get_value.value_name, }) { match handler .handle( (object.clone(), get_value.value_name.clone()), operation_state.clone(), ) .await { Ok(success) => { // self.value_update(in_object, success.clone(), operation_state) // .await; return Ok(*(Box::new((value_meta.serialize)(success).unwrap()) as Box) .downcast() .unwrap()); } Err(err) => { match err { OperationError::Operation(operation_error) => { return Err(OperationError::Operation(operation_error)); } OperationError::Internal(internal) => { // This DOES NOT result in an early return warn!("An internal error occurred during a failable handler operation. {:?}", internal); } OperationError::Unhandled => { // This DOES NOT result in an early return } } } } } if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair { object_kind: object.kind(), value_kind: "any", }) { match handler .handle( (object.clone(), get_value.value_name.clone()), operation_state.clone(), ) .await { Ok(success) => { // self.value_update(in_object, success.clone(), operation_state) // .await; return Ok(*(Box::new((value_meta.serialize)(success).unwrap()) as Box) .downcast() .unwrap()); } Err(err) => { match err { OperationError::Operation(operation_error) => { return Err(OperationError::Operation(operation_error)); } OperationError::Internal(internal) => { // This DOES NOT result in an early return warn!("An internal error occurred during a failable handler operation. {:?}", internal); } OperationError::Unhandled => { // This DOES NOT result in an early return } } } } } if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair { object_kind: "any", value_kind: "any", }) { match handler .handle( (object.clone(), get_value.value_name.clone()), operation_state.clone(), ) .await { Ok(success) => { // self.value_update(in_object, success.clone(), operation_state) // .await; return Ok(*(Box::new((value_meta.serialize)(success).unwrap()) as Box) .downcast() .unwrap()); } Err(err) => { match err { OperationError::Operation(operation_error) => { return Err(OperationError::Operation(operation_error)); } OperationError::Internal(internal) => { // This DOES NOT result in an early return warn!("An internal error occurred during a failable handler operation. {:?}", internal); } OperationError::Unhandled => { // This DOES NOT result in an early return } } } } } if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair { object_kind: object.kind(), value_kind: &get_value.value_name, }) { match handler .handle( (object.clone(), get_value.value_name.clone()), operation_state.clone(), ) .await { Ok(success) => { // self.value_update(in_object, success.clone(), operation_state) // .await; return Ok(AnySuccess(Arc::new( (value_meta.serialize)(success) .as_internal_error_with_context("serializing value")?, ))); } Err(err) => { match err { OperationError::Operation(operation_error) => { return Err(OperationError::Operation(operation_error)); } OperationError::Internal(internal) => { // This DOES NOT result in an early return warn!("An internal error occurred during a failable handler operation. {:?}", internal); } OperationError::Unhandled => { // This DOES NOT result in an early return } } } } } } else if operation.is::() { let get_setting: &GetSetting = operation.downcast_ref().unwrap(); let setting_name = get_setting.setting_name.clone(); let raw_result = self .get_setting( object.clone(), object.kind().to_string(), get_setting.clone(), &operation_state, ) .await; let setting_meta = self .metadata .settings .get(&ObjectSettingPair { object_kind: object.kind(), setting_name: &get_setting.setting_name, }) .ok_or_else(|| OperationError::Unhandled)?; return match raw_result { Ok(success) => { // Success is the setting type, serialize it // let serialized = (setting_meta.serialize)(success).unwrap(); // Ok(serde_json::to_vec(&serialized).unwrap()) // Ok(success.downcast_ref::().unwrap().clone()) Ok(AnySuccess(Arc::new( (setting_meta.serialize)(success).unwrap(), ))) } Err(err) => Err(match err { OperationError::Operation(failure) => { // We know this is the right type OperationError::Operation(*failure.downcast().unwrap()) } OperationError::Internal(internal) => { OperationError::Internal(internal.context(format!( "{}::get_setting::<{}> handler outcome", object.kind(), setting_name ))) } OperationError::Unhandled => OperationError::Unhandled, }), }; } else if operation.is::() { let operation: &SetSetting = operation.downcast_ref().unwrap(); let object_type = object.kind(); trace!( "Handling {}::set_setting for {}", object_type, operation.setting_name ); let setting_meta = self .metadata .settings .get(&ObjectSettingPair { object_kind: &object_type, setting_name: &operation.setting_name, }) // TODO: Check this .ok_or(OperationError::Operation(AnyFailure(Arc::new( SetSettingError::InvalidSetting( operation.setting_name.clone(), object_type.to_string().clone(), ), ))))?; let setting = (setting_meta.deserialize)(operation.value.clone()) .as_internal_error_with_context(format!( "deserializing setting {} for object {}", operation.setting_name, object_type ))?; trace!( "Deserialized setting {} for object {}", operation.setting_name, object_type, ); for provider in self.metadata_providers.iter() { if provider.provides_for(object.deref()) { trace!( "Resolved setting provider for setting {} for object {}", operation.setting_name, object_type, ); let object_meta = self .metadata .objects .get(object_type) .ok_or_else(|| OperationError::Unhandled)?; let raw_result = provider .write(object.clone(), object_meta, setting.clone(), setting_meta) .await; return match raw_result { Ok(_) => { warn!("Setting updated not implemented"); // (setting_meta.setting_updated)( // object, // setting, // self.clone(), // operation_state, // ) // .await; Ok(AnySuccess(Arc::new(()))) } Err(e) => Err(OperationError::Internal(e.context(format!( "writing object {} setting {}", object_type, operation.setting_name )))), }; } trace!( "Failed to resolve setting provider for setting {} for object {}", operation.setting_name, object_type, ); } } else if operation.is::() { let object_request: &ObjectRequest = operation.downcast_ref().unwrap(); trace!("handling object request for {}", object_request.0); // TODO: Authorization? for (_object_name, object_meta) in self.inner.metadata.objects.iter() { if object_meta.name == "networked_object" { // TODO: HACK continue; } if let Ok(object) = (object_meta.from_str)(&object_request.0) { trace!("object request resolved as type {}", object_meta.name); return Ok(AnySuccess(Arc::new(ObjectResponse((object_meta.to_str)( object, ))))); } } if let Some(handler) = self.operation_handlers.get(&ObjectOperationPair { object_name: "any", operation_name: "any", }) { let result = handler .handle( ( AnyObject::new(Instance::from_str("giterated.dev").unwrap()), AnyOperation::new(ObjectRequest(object_request.0.to_string())), ), operation_state.clone(), ) .await; match result { Ok(success) => { let object: &ObjectResponse = success.0.downcast_ref().unwrap(); return Ok(AnySuccess(Arc::new(object.clone()))); } Err(_err) => { todo!() } } } return Err(OperationError::Unhandled); } trace!( "Object operation for {}::{} is not special case", object.kind(), operation_name ); // Resolve the handler from our handler tree let handler_tree = self .inner .operation_handlers .get(&operation.kind()) .ok_or_else(|| OperationError::Unhandled)?; trace!( "Object operation for {}::{} handler tree resolved", object.kind(), operation_name ); handler_tree .handle((object, operation), operation_state.clone()) .await } } /// Defines a type that is a valid Giterated runtime state. /// /// This allows for extraction of state in handlers, based on a /// [`FromOperationState`] impl on (what is in this case) [`Self`]. pub trait GiteratedStackState: Send + Sync + Clone {} impl GiteratedStackState for T {} #[async_trait::async_trait(?Send)] impl HandlerResolvable for Option where T: HandlerResolvable, { type Error = MissingValue; async fn from_handler_state( required_parameters: &R, operation_state: &S, ) -> Result, MissingValue> { Ok(T::from_handler_state(required_parameters, operation_state) .await .ok()) } }