JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

More progress :)

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨92c3f32

⁨giterated-plugin/src/vtable/setting.rs⁩ - ⁨2424⁩ bytes
Raw
1 use std::mem::transmute;
2
3 use giterated_models::{
4 instance::Instance,
5 settings::{GetSetting, Setting},
6 };
7
8 use crate::{AnySuccess, FFIBox};
9
10 use super::OperationVTable;
11
12 #[repr(C)]
13 pub struct NewAnySetting {
14 /// A pointer to the plugin-local object type. We are not capable of
15 /// knowing what this type is, we use the provided vtable.
16 inner: FFIBox<()>,
17 pub vtable: SettingVtable,
18 }
19
20 impl NewAnySetting {
21 pub fn new<V: IntoSettingVTable>(value: V) -> Self {
22 Self {
23 inner: FFIBox::from_box(Box::new(value)).untyped(),
24 vtable: SettingVtable::new::<V>(),
25 }
26 }
27
28 pub unsafe fn transmute_owned<T>(self) -> Box<T> {
29 Box::from_raw(self.inner.0 as *mut T)
30 }
31
32 pub unsafe fn transmute_ref<T>(&self) -> &T {
33 let ptr: *const T = transmute(self.inner.0);
34
35 ptr.as_ref().unwrap()
36 }
37 }
38
39 impl From<NewAnySetting> for AnySuccess {
40 fn from(val: NewAnySetting) -> Self {
41 unsafe { AnySuccess::from_raw(val.inner, (val.vtable.get_setting_vtable)()) }
42 }
43 }
44
45 #[derive(Clone, Copy)]
46 #[repr(C)]
47 pub struct SettingVtable {
48 pub get_setting_vtable: unsafe extern "C" fn() -> OperationVTable,
49
50 pub deserialize: unsafe extern "C" fn(&[u8]) -> Result<(), ()>,
51 pub serialize: unsafe extern "C" fn(NewAnySetting) -> Result<FFIBox<[u8]>, ()>,
52 }
53
54 impl SettingVtable {
55 pub fn new<T: IntoSettingVTable>() -> Self {
56 Self {
57 get_setting_vtable: T::get_setting_vtable,
58 deserialize: T::deserialize,
59 serialize: T::serialize,
60 }
61 }
62 }
63
64 pub trait IntoSettingVTable {
65 unsafe extern "C" fn get_setting_vtable() -> OperationVTable;
66 unsafe extern "C" fn deserialize(src: &[u8]) -> Result<(), ()>;
67 unsafe extern "C" fn serialize(this: NewAnySetting) -> Result<FFIBox<[u8]>, ()>;
68 }
69
70 impl<S> IntoSettingVTable for S
71 where
72 S: Setting,
73 {
74 unsafe extern "C" fn deserialize(_src: &[u8]) -> Result<(), ()> {
75 todo!()
76 }
77
78 unsafe extern "C" fn serialize(this: NewAnySetting) -> Result<FFIBox<[u8]>, ()> {
79 let setting = this.transmute_owned::<S>();
80
81 let serialized = serde_json::to_vec(&setting).unwrap();
82
83 let serialized = serialized.into_boxed_slice();
84
85 Ok(FFIBox::from_box(serialized))
86 }
87
88 unsafe extern "C" fn get_setting_vtable() -> OperationVTable {
89 OperationVTable::new::<Instance, GetSetting>()
90 }
91 }
92