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

ambee/giterated

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

Huge refactor to prep for moving the daemon over to the plugin architecture

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5df753c

⁨giterated-plugins/giterated-plugin/src/vtable/object.rs⁩ - ⁨2931⁩ bytes
Raw
1 use std::mem::transmute;
2
3 use giterated_models::object::GiteratedObject;
4
5 use crate::FFIBox;
6
7 #[derive(Clone, Copy)]
8 #[repr(C)]
9 pub struct ObjectVtable {
10 object_kind: *const u8,
11 object_kind_len: usize,
12 pub to_str: unsafe extern "C" fn(AnyObject) -> FFIBox<str>,
13 pub from_str: unsafe extern "C" fn(&str) -> Result<AnyObject, FFIBox<str>>,
14 pub home_uri: unsafe extern "C" fn(&AnyObject) -> FFIBox<str>,
15 pub is_same: unsafe extern "C" fn(AnyObject) -> bool,
16 }
17
18 impl ObjectVtable {
19 pub fn new<T: IntoObjectVTable>() -> Self {
20 let object_kind = T::object_kind().as_ptr();
21 let object_kind_len = T::object_kind().len();
22
23 Self {
24 to_str: T::to_str,
25 from_str: T::from_str,
26 home_uri: T::home_uri,
27 is_same: T::is_same,
28 object_kind,
29 object_kind_len,
30 }
31 }
32
33 pub fn kind(&self) -> &'static str {
34 let slice = unsafe { std::slice::from_raw_parts(self.object_kind, self.object_kind_len) };
35
36 std::str::from_utf8(slice).unwrap()
37 }
38 }
39
40 pub trait IntoObjectVTable {
41 fn object_kind() -> &'static str;
42 unsafe extern "C" fn to_str(this: AnyObject) -> FFIBox<str>;
43 unsafe extern "C" fn from_str(src: &str) -> Result<AnyObject, FFIBox<str>>;
44 unsafe extern "C" fn home_uri(this: &AnyObject) -> FFIBox<str>;
45 unsafe extern "C" fn is_same(other: AnyObject) -> bool;
46 }
47
48 impl<T: GiteratedObject + 'static> IntoObjectVTable for T {
49 unsafe extern "C" fn to_str(mut this: AnyObject) -> FFIBox<str> {
50 let this: &Box<T> = this.transmute_ref();
51
52 let result = this.to_string();
53
54 FFIBox::from_box(result.into_boxed_str())
55 }
56
57 unsafe extern "C" fn from_str(src: &str) -> Result<AnyObject, FFIBox<str>> {
58 let result = T::from_object_str(src).unwrap();
59
60 let any_object = AnyObject::new(result);
61
62 Ok(any_object)
63 }
64
65 unsafe extern "C" fn home_uri(this: &AnyObject) -> FFIBox<str> {
66 todo!()
67 }
68
69 unsafe extern "C" fn is_same(other: AnyObject) -> bool {
70 todo!()
71 }
72
73 fn object_kind() -> &'static str {
74 todo!()
75 }
76 }
77
78 #[repr(C)]
79 pub struct AnyObject {
80 /// A pointer to the plugin-local object type. We are not capable of
81 /// knowing what this type is, we use the provided vtable.
82 inner: FFIBox<()>,
83 vtable: ObjectVtable,
84 }
85
86 impl AnyObject {
87 pub fn new<T: IntoObjectVTable>(inner: T) -> Self {
88 Self {
89 inner: FFIBox::from_box(Box::new(inner)).untyped(),
90 vtable: ObjectVtable::new::<T>(),
91 }
92 }
93
94 pub fn vtable(&self) -> ObjectVtable {
95 self.vtable
96 }
97 }
98
99 impl AnyObject {
100 pub unsafe fn transmute_owned<T>(&mut self) -> Box<T> {
101 Box::from_raw(self.inner.0 as *mut T)
102 }
103
104 pub unsafe fn transmute_ref<T>(&self) -> &T {
105 let ptr: *const T = transmute(self.inner.0);
106
107 ptr.as_ref().unwrap()
108 }
109 }
110