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/operation.rs⁩ - ⁨5811⁩ bytes
Raw
1 use std::mem::transmute;
2
3 use giterated_models::{object::GiteratedObject, operation::GiteratedOperation};
4
5 use crate::FFIBox;
6
7 #[derive(Clone, Copy)]
8 #[repr(C)]
9 pub struct OperationVTable {
10 operation_kind: *const u8,
11 operation_kind_len: usize,
12 pub serialize: unsafe extern "C" fn(&AnyOperation) -> Result<FFIBox<[u8]>, ()>,
13 pub deserialize: unsafe extern "C" fn(&[u8]) -> Result<AnyOperation, ()>,
14 pub is_same: unsafe extern "C" fn(&AnyOperation) -> bool,
15 pub serialize_success: unsafe extern "C" fn(()) -> Result<FFIBox<[u8]>, ()>,
16 pub serialize_failure: unsafe extern "C" fn(()) -> Result<FFIBox<[u8]>, ()>,
17 pub deserialize_success: unsafe extern "C" fn(&[u8]) -> Result<AnySuccess, ()>,
18 pub deserialize_failure: unsafe extern "C" fn(&[u8]) -> Result<AnyFailure, ()>,
19 }
20
21 impl OperationVTable {
22 pub fn new<O, T: IntoOperationVTable<O>>() -> Self {
23 let operation_kind = T::operation_kind().as_ptr();
24 let operation_kind_len = T::operation_kind().len();
25
26 Self {
27 serialize: T::serialize,
28 deserialize: T::deserialize,
29 is_same: T::is_same,
30 serialize_success: T::serialize_success,
31 serialize_failure: T::serialize_failure,
32 deserialize_success: T::deserialize_success,
33 deserialize_failure: T::deserialize_failure,
34 operation_kind,
35 operation_kind_len,
36 }
37 }
38
39 pub fn kind(&self) -> &'static str {
40 let slice =
41 unsafe { std::slice::from_raw_parts(self.operation_kind, self.operation_kind_len) };
42
43 std::str::from_utf8(slice).unwrap()
44 }
45 }
46
47 #[repr(C)]
48 pub struct AnyOperation {
49 /// A pointer to the plugin-local object type. We are not capable of
50 /// knowing what this type is, we use the provided vtable.
51 inner: FFIBox<()>,
52 vtable: OperationVTable,
53 }
54
55 impl AnyOperation {
56 pub fn new<O: GiteratedObject, D: GiteratedOperation<O>>(_operation: D) -> Self {
57 todo!()
58 }
59
60 pub unsafe fn transmute_owned<T>(&mut self) -> Box<T> {
61 Box::from_raw(self.inner.0 as *mut T)
62 }
63
64 pub unsafe fn transmute_ref<T>(&self) -> &T {
65 let ptr: *const T = transmute(self.inner.0);
66
67 ptr.as_ref().unwrap()
68 }
69
70 pub fn vtable(&self) -> OperationVTable {
71 self.vtable
72 }
73
74 pub fn operation_kind(&self) -> &str {
75 unsafe {
76 std::str::from_utf8_unchecked(std::slice::from_raw_parts(
77 self.vtable.operation_kind,
78 self.vtable.operation_kind_len,
79 ))
80 }
81 }
82
83 pub fn serialize(&self) -> Result<Vec<u8>, anyhow::Error> {
84 todo!()
85 }
86
87 pub fn deserialize(_source: &[u8], _vtable: OperationVTable) -> Result<Self, anyhow::Error> {
88 todo!()
89 }
90
91 pub fn is_same(&self, _other: &AnyOperation) -> bool {
92 todo!()
93 }
94 }
95
96 #[repr(C)]
97 pub struct AnySuccess {
98 inner: FFIBox<()>,
99 vtable: OperationVTable,
100 }
101
102 impl AnySuccess {
103 pub unsafe fn inner<T: Send + Sync>(&self) -> &T {
104 self.inner.transmute_ref()
105 }
106
107 pub unsafe fn from_raw(inner: FFIBox<()>, vtable: OperationVTable) -> Self {
108 Self { inner, vtable }
109 }
110
111 pub fn serialize(&self) -> Result<Vec<u8>, anyhow::Error> {
112 todo!()
113 }
114
115 pub fn deserialize_from_operation(
116 _source: &[u8],
117 _vtable: OperationVTable,
118 ) -> Result<Self, anyhow::Error> {
119 todo!()
120 }
121 }
122
123 unsafe impl Send for AnySuccess {}
124 unsafe impl Sync for AnySuccess {}
125
126 impl std::fmt::Debug for AnySuccess {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 f.debug_struct("AnySuccess").finish()
129 }
130 }
131
132 #[repr(C)]
133 pub struct AnyFailure {
134 inner: FFIBox<()>,
135 vtable: OperationVTable,
136 }
137
138 unsafe impl Send for AnyFailure {}
139 unsafe impl Sync for AnyFailure {}
140
141 impl std::fmt::Debug for AnyFailure {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 f.debug_struct("AnyFailure").finish()
144 }
145 }
146
147 pub trait IntoOperationVTable<O> {
148 fn operation_kind() -> &'static str;
149 unsafe extern "C" fn serialize(this: &AnyOperation) -> Result<FFIBox<[u8]>, ()>;
150 unsafe extern "C" fn deserialize(src: &[u8]) -> Result<AnyOperation, ()>;
151 unsafe extern "C" fn is_same(this: &AnyOperation) -> bool;
152 unsafe extern "C" fn serialize_success(success: ()) -> Result<FFIBox<[u8]>, ()>;
153 unsafe extern "C" fn serialize_failure(failure: ()) -> Result<FFIBox<[u8]>, ()>;
154 unsafe extern "C" fn deserialize_success(src: &[u8]) -> Result<AnySuccess, ()>;
155 unsafe extern "C" fn deserialize_failure(src: &[u8]) -> Result<AnyFailure, ()>;
156 }
157
158 impl<O, D> IntoOperationVTable<O> for D
159 where
160 D: GiteratedOperation<O>,
161 O: GiteratedObject,
162 {
163 unsafe extern "C" fn serialize(_this: &AnyOperation) -> Result<FFIBox<[u8]>, ()> {
164 todo!()
165 }
166
167 unsafe extern "C" fn deserialize(src: &[u8]) -> Result<AnyOperation, ()> {
168 let deserialized: D = serde_json::from_slice(src).unwrap();
169
170 Ok(AnyOperation {
171 inner: FFIBox::from_box(Box::new(deserialized)).untyped(),
172 vtable: OperationVTable::new::<O, D>(),
173 })
174 }
175
176 unsafe extern "C" fn is_same(_this: &AnyOperation) -> bool {
177 todo!()
178 }
179
180 unsafe extern "C" fn serialize_success(_success: ()) -> Result<FFIBox<[u8]>, ()> {
181 todo!()
182 }
183
184 unsafe extern "C" fn serialize_failure(_failure: ()) -> Result<FFIBox<[u8]>, ()> {
185 todo!()
186 }
187
188 unsafe extern "C" fn deserialize_success(_src: &[u8]) -> Result<AnySuccess, ()> {
189 todo!()
190 }
191
192 unsafe extern "C" fn deserialize_failure(_src: &[u8]) -> Result<AnyFailure, ()> {
193 todo!()
194 }
195
196 fn operation_kind() -> &'static str {
197 <D as GiteratedOperation<_>>::operation_name()
198 }
199 }
200