use std::{any::type_name, fmt::Debug, marker::PhantomData}; use anyhow::Error; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde_json::Value; use crate::{ error::{GetValueError, OperationError}, model::{instance::Instance, settings::Setting, MessageTarget}, values::{GetSetting, GetSettingError, SetSetting, SetSettingError}, }; pub mod instance; pub mod repository; pub mod user; pub trait GiteratedObject: Send + Serialize + DeserializeOwned + ToString { fn object_name() -> &'static str; fn from_object_str(object_str: &str) -> Result; } pub trait GiteratedOperation: Send + Serialize + DeserializeOwned { type Success: Serialize + DeserializeOwned + Send; type Failure: Serialize + DeserializeOwned + Send; fn operation_name() -> &'static str { type_name::() } } pub trait GiteratedObjectValue: Serialize + DeserializeOwned { type Object: GiteratedObject; fn value_name() -> &'static str; } #[derive(Debug, Clone)] pub struct Object<'b, O: GiteratedObject, B: ObjectBackend + 'b + Send + Sync + Clone> { inner: O, backend: B, _marker: PhantomData<&'b ()>, } #[async_trait::async_trait] pub trait ObjectBackend: Send + Sync + Sized + Clone { async fn object_operation + Debug>( &self, object: O, operation: D, ) -> Result>; async fn get_object( &self, object_str: &str, ) -> Result, OperationError>; } impl<'b, B: ObjectBackend + Send + Sync + Clone, O: GiteratedObject> Object<'b, O, B> { pub unsafe fn new_unchecked(object: O, backend: B) -> Object<'b, O, B> { Object { inner: object, backend, _marker: PhantomData, } } } // impl<'b, O: GiteratedObject, B: ObjectBackend> Object<'b, O, B> { // pub unsafe fn new_unchecked(value: O, backend: Arc) -> Object<'b, O, B> { // todo!() // } // } impl<'b, O: GiteratedObject + Clone + Debug, B: ObjectBackend + Debug + Send + Sync + Clone> Object<'b, O, B> { // pub async fn get + Send>( // &self, // ) -> Result> { // let operation: GetValue = GetValue { // value_name: V::value_name().to_string(), // _marker: PhantomData, // }; // let _message: GiteratedMessage = GiteratedMessage { // object: self.inner.clone(), // operation: operation.operation_name().to_string(), // payload: operation, // }; // todo!() // } // pub fn request + Debug>( // &mut self, // request: R, // ) -> Result { // self.backend.object_operation(self.inner.clone(), request); // todo!() // } } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct GetValue { pub value_name: String, _marker: PhantomData, } impl + Send> GiteratedOperation for GetValue { fn operation_name() -> &'static str { "get_value" } type Success = V; type Failure = GetValueError; } #[derive(Serialize)] #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation"))] pub struct GiteratedMessage> { pub object: O, pub operation: String, pub payload: V, } impl GiteratedMessage { pub fn try_into>( &self, ) -> Result, ()> { let object = O::from_object_str(&self.object.0).map_err(|_| ())?; let payload = serde_json::from_value::(self.payload.0.clone()).map_err(|_| ())?; Ok(GiteratedMessage { object, operation: self.operation.clone(), payload, }) } } impl> MessageTarget for GiteratedMessage {} impl + Debug, O: GiteratedObject + Debug> Debug for GiteratedMessage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("GiteratedMessage") .field("object", &self.object) .field("operation", &self.operation) .field("payload", &self.payload) .finish() } } #[derive(Debug, Serialize, Deserialize)] pub struct ObjectRequest(pub String); #[derive(Serialize, Deserialize)] pub struct ObjectResponse(pub Vec); impl GiteratedOperation for ObjectRequest { type Success = ObjectResponse; type Failure = ObjectRequestError; } #[derive(Debug, thiserror::Error, Serialize, Deserialize)] pub enum ObjectRequestError { #[error("error decoding the object")] Deserialization(String), } #[derive(Clone, Debug, Serialize, Deserialize)] #[repr(transparent)] pub struct AnyObject(pub String); impl GiteratedObject for AnyObject { fn object_name() -> &'static str { "any" } fn from_object_str(object_str: &str) -> Result { Ok(Self(object_str.to_string())) } } impl ToString for AnyObject { fn to_string(&self) -> String { self.0.to_string() } } #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(transparent)] #[repr(transparent)] pub struct AnyOperation(pub Value); impl GiteratedOperation for AnyOperation { type Success = Vec; type Failure = Vec; } impl<'b, O: GiteratedObject + Clone + Debug, B: ObjectBackend> Object<'b, O, B> { pub async fn get + Send + Debug>( &mut self, ) -> Result> { self.request(GetValue { value_name: V::value_name().to_string(), _marker: PhantomData, }) .await } pub async fn get_setting( &mut self, ) -> Result> { self.request(GetSetting { setting_name: S::name().to_string(), _marker: PhantomData, }) .await } pub async fn set_setting( &mut self, setting: S, ) -> Result<(), OperationError> { self.request(SetSetting { setting_name: S::name().to_string(), value: setting, }) .await } pub async fn request + Debug>( &mut self, request: R, ) -> Result> { self.backend .object_operation(self.inner.clone(), request) .await } }