use std::{any::Any, sync::Arc}; pub mod handler_impl; use futures_util::{future::LocalBoxFuture, Future, FutureExt}; use giterated_models::error::OperationError; use crate::{ AuthenticatedInstance, AuthenticatedUser, GiteratedStack, MissingValue, StackOperationState, }; #[async_trait::async_trait(?Send)] pub trait IntoGiteratedHandler where // Output cannot have non-static references Output: 'static, { type Future: Future; async fn handle(&self, parameters: Params, state: State, operation_state: OState) -> Output; } pub struct HandlerTree { elements: Vec, } impl Default for HandlerTree { fn default() -> Self { Self { elements: Default::default(), } } } impl<'fut: 'o + 'p, 'p, 'o, P, O, E> HandlerTree> where P: Clone, { pub fn push(&mut self, handler: HandlerWrapper) { self.elements.push(handler); } pub async fn handle( &self, parameters: P, operation_state: StackOperationState, ) -> Result> { for handler in self.elements.iter() { match handler .handle(parameters.clone(), operation_state.clone()) .await { Ok(handled) => return Ok(handled), Err(err) => match err { OperationError::Internal(err) => return Err(OperationError::Internal(err)), OperationError::Operation(err) => return Err(OperationError::Operation(err)), OperationError::Unhandled => continue, }, } } Err(OperationError::Unhandled) } } pub struct HandlerWrapper { func: Arc< dyn Fn( P, Arc, StackOperationState, ) -> LocalBoxFuture<'static, Result>> + Send + Sync, >, state: Arc, } impl HandlerWrapper { pub fn new(state: S, handler: F) -> Self where F: IntoGiteratedHandler>> + Send + Sync, S: Send + Sync + Clone + 'static, E: 'static, P: 'static + Clone, F: 'static, O: 'static, { let state = Arc::new(state); let handler_func = Arc::new(handler); let state_two = state.clone(); HandlerWrapper { func: Arc::new( move |args: P, state: Arc, operation_state: StackOperationState| { let handler = handler_func.clone(); let operation_state = operation_state.clone(); let state = state.downcast_ref::().unwrap(); let state = state.clone(); async move { let handler = handler.clone(); let operation_state = operation_state; handler.handle(args, state, operation_state).await } .boxed_local() }, ), state: state_two, } } pub async fn handle( &self, required: P, operation_state: StackOperationState, ) -> Result> { (self.func)(required, self.state.clone(), operation_state).await } pub fn map(self, predicate: F) -> HandlerWrapper where F: Fn(&N, &StackOperationState) -> Result> + Clone + Send + Sync, R: std::fmt::Debug + 'static, E: Into> + 'static, F: 'static, N: 'static, P: 'static, O: 'static, { let func = Arc::new(self.func); let predicate = Arc::new(predicate); HandlerWrapper { func: Arc::new( move |args: N, state: Arc, operation_state: StackOperationState| { let predicate_output = predicate(&args, &operation_state); let func = func.clone(); let operation_state: StackOperationState = operation_state.clone(); async move { let predicate_output = predicate_output?; let operation_state = operation_state; match (func)(predicate_output, state, operation_state).await { Ok(success) => Ok(success), Err(_) => todo!(), } } .boxed_local() }, ), state: self.state, } } pub fn map_return(self, predicate: F) -> HandlerWrapper where F: Fn(Result>, &StackOperationState) -> Result> + Clone + Send + Sync, O: 'static, F: 'static, E: 'static, P: 'static, { let predicate = Arc::new(predicate); let func = self.func; HandlerWrapper { func: Arc::new( move |args: P, state: Arc, operation_state: StackOperationState| { let clone = predicate.clone(); let func = func.clone(); let _statoperation_statee = operation_state.clone(); async move { let func = func.clone(); let clone = clone; let operation_state = operation_state; clone( (func)(args, state, operation_state.clone()).await, &operation_state, ) } .boxed_local() }, ), state: self.state, } } } #[async_trait::async_trait(?Send)] pub trait HandlerResolvable: Sized { type Error; async fn from_handler_state( required_parameters: &RequiredParameters, operation_state: &OperationState, ) -> Result; } #[async_trait::async_trait(?Send)] impl HandlerResolvable for Arc { type Error = MissingValue; async fn from_handler_state( _required_parameters: &R, operation_state: &StackOperationState, ) -> Result { Ok(operation_state.runtime.clone()) } } #[async_trait::async_trait(?Send)] impl HandlerResolvable for AuthenticatedUser { type Error = MissingValue; async fn from_handler_state( _required_parameters: &R, operation_state: &StackOperationState, ) -> Result { operation_state.user.clone().ok_or_else(|| MissingValue) } } #[async_trait::async_trait(?Send)] impl HandlerResolvable for AuthenticatedInstance { type Error = MissingValue; async fn from_handler_state( _required_parameters: &R, operation_state: &StackOperationState, ) -> Result { operation_state.instance.clone().ok_or_else(|| MissingValue) } }