use giterated_models::{ error::OperationError, object::{self, GiteratedObject, ObjectRequestError}, object_backend::ObjectBackend, operation::{GiteratedOperation, OperationState}, }; use crate::{ result::{FfiError, FfiResult}, state::State, value_ex::FfiValueUntyped, FfiFuture, FfiSliceRef, FfiValueMut, StackPinned, }; use core::fmt::Debug; use super::{Object, ObjectABI, VTable}; #[derive(Clone)] pub struct RuntimeHandle { pub vtable: &'static VTable, } impl ObjectABI for RuntimeHandle { type VTable = RuntimeVTable; } impl RuntimeHandle { pub async fn handle_serialized( &self, object: &str, operation_type: &str, operation_payload: &[u8], ) -> Result, OperationError>> { todo!() } pub async fn handle_typed( &self, object: O, operation: D, ) -> Result> where O: GiteratedObject, D: GiteratedOperation, { todo!() } pub fn inner_get_object( &self, object_str: &str, state: &mut State, ) -> Result> { let pinned_object_str = (*object_str.as_bytes()).pin(); let mut pinned_state = (*state).pin(); let result = unsafe { (self.vtable.get_object)(unsafe { pinned_object_str.grant_ref() }, unsafe { pinned_state.grant_mut() }) }; todo!() } } #[derive(Clone, Copy)] pub struct RuntimeVTable { pub(crate) handle_fn: unsafe extern "C" fn( FfiSliceRef, FfiSliceRef, FfiSliceRef, FfiSliceRef<[u8]>, FfiSliceRef<[u8]>, ) -> FfiFuture< FfiResult>, >, pub(crate) get_object: unsafe extern "C" fn( object_str: FfiSliceRef, state: FfiValueMut, ) -> FfiResult>, } impl RuntimeVTable { pub const fn new() -> RuntimeVTable { RuntimeVTable { handle_fn: R::handle, get_object: R::get_object, } } } unsafe impl Send for RuntimeVTable {} unsafe impl Sync for RuntimeVTable {} pub trait IntoRuntimeVtable: Sized { const VTABLE: RuntimeVTable = RuntimeVTable::new::(); unsafe extern "C" fn handle( object_kind: FfiSliceRef, operation_name: FfiSliceRef, object: FfiSliceRef, operation_payload: FfiSliceRef<[u8]>, operation_state: FfiSliceRef<[u8]>, ) -> FfiFuture>>; unsafe extern "C" fn get_object( object_str: FfiSliceRef, operation_state: FfiValueMut, ) -> FfiResult>; } #[async_trait::async_trait(?Send)] impl ObjectBackend for RuntimeHandle { async fn object_operation( &self, object: O, operation: &str, payload: D, operation_state: &mut State, ) -> Result> where O: GiteratedObject + Debug + 'static, D: GiteratedOperation + Debug + 'static, D::Success: Clone, D::Failure: Clone, { todo!() } async fn get_object( &self, object_str: &str, operation_state: &mut State, ) -> Result, OperationError> { let result = self.inner_get_object(object_str, operation_state)?; Ok(unsafe { object::Object::new_unchecked(result.cast(), self.clone()) }) } }