use giterated_models::{ error::OperationError, object::{ AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse, }, object_backend::ObjectBackend, operation::{AnyOperation, GiteratedOperation}, }; use std::{fmt::Debug, str::FromStr, sync::Arc}; use tracing::warn; use crate::{state::HandlerState, OperationHandlers}; #[derive(Clone)] pub struct GiteratedBackend { state: S, handlers: Arc>, } impl GiteratedBackend { pub fn new(state: S, handlers: OperationHandlers) -> Self { Self { state, handlers: Arc::new(handlers), } } } #[async_trait::async_trait] impl ObjectBackend for GiteratedBackend { async fn object_operation( &self, object: O, operation: &str, payload: D, ) -> Result> where O: GiteratedObject + Debug, D: GiteratedOperation + Debug, { let serialized = serde_json::to_value(payload).map_err(|e| OperationError::Internal(e.to_string()))?; let object = object.to_string(); if operation == ObjectRequest::operation_name() { // We're doing an object request let raw_result = self .handlers .resolve_object( AnyObject(object.clone()), serde_json::from_value(serialized).unwrap(), self.state.clone(), ) .await; return match raw_result { Ok(result) => Ok(serde_json::from_slice(&result) .map_err(|e| OperationError::Internal(e.to_string()))?), Err(err) => match err { OperationError::Internal(internal) => { warn!( "Internal Error: {:?}", OperationError::<()>::Internal(internal.clone()) ); Err(OperationError::Internal(internal)) } OperationError::Unhandled => Err(OperationError::Unhandled), OperationError::Operation(err) => Err(OperationError::Operation( serde_json::from_slice(&err) .map_err(|e| OperationError::Internal(e.to_string()))?, )), }, }; } let raw_result = self .handlers .handle( &AnyObject(object), operation, AnyOperation(serialized), self.state.clone(), ) .await; match raw_result { Ok(result) => Ok(serde_json::from_slice(&result) .map_err(|e| OperationError::Internal(e.to_string()))?), Err(err) => match err { OperationError::Internal(internal) => { warn!( "Internal Error: {:?}", OperationError::<()>::Internal(internal.clone()) ); Err(OperationError::Internal(internal)) } OperationError::Unhandled => Err(OperationError::Unhandled), OperationError::Operation(err) => Err(OperationError::Operation( serde_json::from_slice(&err) .map_err(|e| OperationError::Internal(e.to_string()))?, )), }, } } async fn get_object( &self, object_str: &str, ) -> Result, OperationError> { let raw_result = self .handlers .resolve_object( AnyObject("giterated.dev".to_string()), ObjectRequest(object_str.to_string()), self.state.clone(), ) .await; let object: ObjectResponse = match raw_result { Ok(result) => Ok(serde_json::from_slice(&result) .map_err(|e| OperationError::Internal(e.to_string()))?), Err(err) => match err { OperationError::Internal(internal) => { warn!( "Internal Error: {:?}", OperationError::<()>::Internal(internal.clone()) ); Err(OperationError::Internal(internal)) } OperationError::Unhandled => Err(OperationError::Unhandled), OperationError::Operation(err) => Err(OperationError::Operation( serde_json::from_slice(&err) .map_err(|e| OperationError::Internal(e.to_string()))?, )), }, }?; unsafe { Ok(Object::new_unchecked( O::from_str(&object.0) .map_err(|_| OperationError::Internal("deserialize failure".to_string()))?, self.clone(), )) } } }