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

ambee/giterated

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

Fucking whatever there you go

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨57c2ca5

⁨giterated-plugin/src/vtable/operation.rs⁩ - ⁨4157⁩ bytes
Raw
1 use std::mem::transmute;
2
3 use giterated_models::{object::GiteratedObject, operation::GiteratedOperation};
4
5 use crate::FFIBox;
6
7 use super::AnyObject;
8
9 #[derive(Clone, Copy)]
10 #[repr(C)]
11 pub struct OperationVTable {
12 operation_kind: *const u8,
13 operation_kind_len: usize,
14 pub serialize: unsafe extern "C" fn(&AnyOperation) -> Result<FFIBox<[u8]>, ()>,
15 pub deserialize: unsafe extern "C" fn(&[u8]) -> Result<AnyOperation, ()>,
16 pub is_same: unsafe extern "C" fn(AnyObject) -> bool,
17 pub serialize_success: unsafe extern "C" fn(()) -> Result<FFIBox<[u8]>, ()>,
18 pub serialize_failure: unsafe extern "C" fn(()) -> Result<FFIBox<[u8]>, ()>,
19 pub deserialize_success: unsafe extern "C" fn(&[u8]) -> Result<AnySuccess, ()>,
20 pub deserialize_failure: unsafe extern "C" fn(&[u8]) -> Result<AnyFailure, ()>,
21 }
22
23 impl OperationVTable {
24 pub fn new<O, T: IntoOperationVTable<O>>() -> Self {
25 let operation_kind = T::operation_kind().as_ptr();
26 let operation_kind_len = T::operation_kind().len();
27
28 Self {
29 serialize: T::serialize,
30 deserialize: T::deserialize,
31 is_same: T::is_same,
32 serialize_success: T::serialize_success,
33 serialize_failure: T::serialize_failure,
34 deserialize_success: T::deserialize_success,
35 deserialize_failure: T::deserialize_failure,
36 operation_kind,
37 operation_kind_len,
38 }
39 }
40
41 pub fn kind(&self) -> &'static str {
42 let slice =
43 unsafe { std::slice::from_raw_parts(self.operation_kind, self.operation_kind_len) };
44
45 std::str::from_utf8(slice).unwrap()
46 }
47 }
48
49 pub struct AnyOperation {
50 /// A pointer to the plugin-local object type. We are not capable of
51 /// knowing what this type is, we use the provided vtable.
52 inner: FFIBox<()>,
53 vtable: OperationVTable,
54 }
55
56 impl AnyOperation {
57 pub unsafe fn transmute_owned<T>(&mut self) -> Box<T> {
58 Box::from_raw(self.inner.0 as *mut T)
59 }
60
61 pub unsafe fn transmute_ref<T>(&self) -> &T {
62 let ptr: *const T = transmute(self.inner.0);
63
64 ptr.as_ref().unwrap()
65 }
66
67 pub fn vtable(&self) -> OperationVTable {
68 self.vtable
69 }
70 }
71
72 #[repr(C)]
73 pub struct AnySuccess {
74 inner: FFIBox<()>,
75 vtable: OperationVTable,
76 }
77
78 #[repr(C)]
79 pub struct AnyFailure {
80 inner: FFIBox<()>,
81 vtable: OperationVTable,
82 }
83
84 pub trait IntoOperationVTable<O> {
85 fn operation_kind() -> &'static str;
86 unsafe extern "C" fn serialize(this: &AnyOperation) -> Result<FFIBox<[u8]>, ()>;
87 unsafe extern "C" fn deserialize(src: &[u8]) -> Result<AnyOperation, ()>;
88 unsafe extern "C" fn is_same(this: AnyObject) -> bool;
89 unsafe extern "C" fn serialize_success(success: ()) -> Result<FFIBox<[u8]>, ()>;
90 unsafe extern "C" fn serialize_failure(failure: ()) -> Result<FFIBox<[u8]>, ()>;
91 unsafe extern "C" fn deserialize_success(src: &[u8]) -> Result<AnySuccess, ()>;
92 unsafe extern "C" fn deserialize_failure(src: &[u8]) -> Result<AnyFailure, ()>;
93 }
94
95 impl<O, D> IntoOperationVTable<O> for D
96 where
97 D: GiteratedOperation<O>,
98 O: GiteratedObject,
99 {
100 unsafe extern "C" fn serialize(this: &AnyOperation) -> Result<FFIBox<[u8]>, ()> {
101 todo!()
102 }
103
104 unsafe extern "C" fn deserialize(src: &[u8]) -> Result<AnyOperation, ()> {
105 let deserialized: D = serde_json::from_slice(src).unwrap();
106
107 Ok(AnyOperation {
108 inner: FFIBox::from_box(Box::new(deserialized)).untyped(),
109 vtable: OperationVTable::new::<O, D>(),
110 })
111 }
112
113 unsafe extern "C" fn is_same(this: AnyObject) -> bool {
114 todo!()
115 }
116
117 unsafe extern "C" fn serialize_success(success: ()) -> Result<FFIBox<[u8]>, ()> {
118 todo!()
119 }
120
121 unsafe extern "C" fn serialize_failure(failure: ()) -> Result<FFIBox<[u8]>, ()> {
122 todo!()
123 }
124
125 unsafe extern "C" fn deserialize_success(src: &[u8]) -> Result<AnySuccess, ()> {
126 todo!()
127 }
128
129 unsafe extern "C" fn deserialize_failure(src: &[u8]) -> Result<AnyFailure, ()> {
130 todo!()
131 }
132
133 fn operation_kind() -> &'static str {
134 todo!()
135 }
136 }
137