use std::mem::transmute; use giterated_models::settings::Setting; use crate::FFIBox; #[repr(C)] pub struct NewAnySetting { /// A pointer to the plugin-local object type. We are not capable of /// knowing what this type is, we use the provided vtable. inner: FFIBox<()>, vtable: SettingVtable, } impl NewAnySetting { pub fn new(value: V) -> Self { Self { inner: FFIBox::from_box(Box::new(value)).untyped(), vtable: SettingVtable::new::(), } } pub unsafe fn transmute_owned(self) -> Box { Box::from_raw(self.inner.0 as *mut T) } pub unsafe fn transmute_ref(&self) -> &T { let ptr: *const T = transmute(self.inner.0); ptr.as_ref().unwrap() } } #[derive(Clone, Copy)] #[repr(C)] pub struct SettingVtable { pub deserialize: unsafe extern "C" fn(&[u8]) -> Result<(), ()>, pub serialize: unsafe extern "C" fn(NewAnySetting) -> Result, ()>, } impl SettingVtable { pub fn new() -> Self { Self { deserialize: T::deserialize, serialize: T::serialize, } } } pub trait IntoSettingVTable { unsafe extern "C" fn deserialize(src: &[u8]) -> Result<(), ()>; unsafe extern "C" fn serialize(this: NewAnySetting) -> Result, ()>; } impl IntoSettingVTable for S where S: Setting, { unsafe extern "C" fn deserialize(src: &[u8]) -> Result<(), ()> { todo!() } unsafe extern "C" fn serialize(this: NewAnySetting) -> Result, ()> { todo!() } }