pub mod handler; pub mod state; use std::{future::Future, pin::Pin, sync::Arc}; use futures_util::FutureExt; use giterated_models::{ error::OperationError, instance::Instance, object::{AnyObject, GiteratedObject, ObjectRequest, ObjectResponse}, operation::{AnyOperation, GiteratedOperation}, }; pub struct OperationHandlers { operations: Vec>, get_object: Vec>, } impl Default for OperationHandlers { fn default() -> Self { Self { operations: Vec::new(), get_object: Vec::new(), } } } impl OperationHandlers { pub fn insert< O: GiteratedObject + Send + Sync, D: GiteratedOperation + 'static, H: GiteratedOperationHandler + Send + Sync + 'static + Clone, >( &mut self, handler: H, ) -> &mut Self { let _operation_name = handler.operation_name().to_string(); let wrapped = OperationWrapper::new(handler); self.operations.push(wrapped); self } pub fn register_object(&mut self) -> &mut Self { let closure = |_: &Instance, operation: ObjectRequest, _state| { async move { if O::from_str(&operation.0).is_ok() { Ok(ObjectResponse(operation.0)) } else { Err(OperationError::Unhandled) } } .boxed() }; let wrapped = OperationWrapper::new(closure); self.get_object.push(wrapped); self } pub async fn handle( &self, object: &O, _operation_name: &str, operation: AnyOperation, state: S, ) -> Result, OperationError>> { for handler in self.operations.iter() { return match handler .handle( AnyObject(object.to_string()), operation.clone(), state.clone(), ) .await { Ok(ok) => Ok(ok), Err(err) => Err(match err { OperationError::Operation(err) => OperationError::Operation(err), OperationError::Internal(err) => OperationError::Internal(err), OperationError::Unhandled => continue, }), }; } Err(OperationError::Unhandled) } pub async fn resolve_object( &self, instance: AnyObject, request: ObjectRequest, state: S, ) -> Result, OperationError>> { for handler in self.get_object.iter() { if let Ok(response) = handler .handle( instance.clone(), AnyOperation(serde_json::to_value(request.clone()).unwrap()), state.clone(), ) .await { return Ok(response); } } Err(OperationError::Unhandled) } } #[async_trait::async_trait] pub trait GiteratedOperationHandler< O: GiteratedObject, D: GiteratedOperation, S: Send + Sync + Clone, > { fn operation_name(&self) -> &str; fn object_name(&self) -> &str; async fn handle( &self, object: &O, operation: D, state: S, ) -> Result>; } #[async_trait::async_trait] impl GiteratedOperationHandler for F where F: FnMut( &O, D, S, ) -> Pin< Box>> + Send>, > + Send + Sync + Clone, O: GiteratedObject + Send + Sync, D: GiteratedOperation + 'static, >::Failure: Send, S: Send + Sync + Clone + 'static, { fn operation_name(&self) -> &str { D::operation_name() } fn object_name(&self) -> &str { O::object_name() } async fn handle( &self, object: &O, operation: D, state: S, ) -> Result> { self.clone()(object, operation, state).await } } pub struct OperationWrapper( Box< dyn Fn( AnyObject, AnyOperation, S, ) -> Pin, OperationError>>> + Send>> + Send + Sync, >, ); impl OperationWrapper { pub fn new< O: GiteratedObject + Send + Sync, D: GiteratedOperation + 'static, F: GiteratedOperationHandler + Send + Sync + 'static + Clone, >( handler: F, ) -> Self { let handler = Arc::new(Box::pin(handler)); Self(Box::new(move |any_object, any_operation, state| { let handler = handler.clone(); async move { let handler = handler.clone(); let object: O = O::from_object_str(&any_object.0).map_err(|_| OperationError::Unhandled)?; let operation: D = serde_json::from_value(any_operation.0.clone()) .map_err(|_| OperationError::Unhandled)?; let result = handler.handle(&object, operation, state).await; result .map(|success| serde_json::to_vec(&success).unwrap()) .map_err(|err| match err { OperationError::Operation(err) => { OperationError::Operation(serde_json::to_vec(&err).unwrap()) } OperationError::Internal(internal) => OperationError::Internal(internal), OperationError::Unhandled => OperationError::Unhandled, }) } .boxed() })) } async fn handle( &self, object: AnyObject, operation: AnyOperation, state: S, ) -> Result, OperationError>> { self.0(object, operation, state).await } }