use std::{ fmt::{Debug, Display}, marker::PhantomData, str::FromStr, }; use anyhow::Error; use crate::{ error::{GetValueError, OperationError}, object_backend::ObjectBackend, operation::GiteratedOperation, settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError, Setting}, value::{GetValueTyped, GiteratedObjectValue}, }; mod operations; pub use operations::*; #[derive(Debug, Clone)] pub struct Object< 'b, S: Clone + Send + Sync, O: GiteratedObject, B: ObjectBackend + 'b + Send + Clone, > { pub(crate) inner: O, pub(crate) backend: B, pub(crate) _marker: PhantomData<&'b S>, } impl<'b, S: Clone + Send + Sync, B: ObjectBackend + Send + Sync + Clone, O: GiteratedObject> Object<'b, S, O, B> { pub fn object(&self) -> &O { &self.inner } pub unsafe fn new_unchecked(object: O, backend: B) -> Object<'b, S, O, B> { Object { inner: object, backend, _marker: PhantomData, } } } impl< S: Clone + Send + Sync, O: GiteratedObject + Display, B: ObjectBackend + Send + Sync + Clone, > Display for Object<'_, S, O, B> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.inner.fmt(f) } } pub trait GiteratedObject: Send + Display + FromStr + Sync + Clone { fn object_name() -> &'static str; fn from_object_str(object_str: &str) -> Result; } impl< 'b, I: Clone + Send + Sync, O: GiteratedObject + Clone + Debug + 'static, B: ObjectBackend, > Object<'b, I, O, B> { pub async fn get + Send + Debug + 'static>( &mut self, operation_state: &I, ) -> Result> { let result = self .request( GetValueTyped:: { value_name: V::value_name().to_string(), ty: Default::default(), }, operation_state, ) .await; Ok(result?) } pub async fn get_setting( &mut self, operation_state: &I, ) -> Result> { self.request( GetSetting { setting_name: S::name().to_string(), }, operation_state, ) .await .map(|success| serde_json::from_value(success).unwrap()) } pub async fn set_setting( &mut self, setting: S, operation_state: &I, ) -> Result<(), OperationError> { self.request( SetSetting { setting_name: S::name().to_string(), value: AnySetting(serde_json::to_value(setting).unwrap()), }, operation_state, ) .await } pub async fn request + Debug + 'static>( &mut self, request: R, operation_state: &I, ) -> Result> { self.backend .object_operation( self.inner.clone(), R::operation_name(), request, operation_state, ) .await } }