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

ambee/giterated

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

`[feature/plugins]` Some plugin work?

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨10a447b

⁨giterated-plugin/src/new_stack/mod.rs⁩ - ⁨13872⁩ bytes
Raw
1 pub mod handle;
2 pub mod operation_walker;
3 pub mod runtime_handler;
4
5 use std::{
6 any::type_name, collections::HashMap, fmt::Debug, marker::PhantomData, mem::transmute,
7 ptr::null_mut, sync::Arc,
8 };
9
10 use giterated_models::{
11 error::OperationError, instance::Instance, object::GiteratedObject,
12 operation::GiteratedOperation,
13 };
14 use semver::Version;
15 use serde::Serialize;
16 use tracing::{debug, debug_span, field::DebugValue, span, trace, trace_span, warn, Level};
17
18 use crate::{
19 callback::{
20 OperationHandlerCallback, SettingChangeCallback, SettingGetterCallback,
21 ValueChangeCallback, ValueGetterCallback,
22 },
23 handle::{PluginHandle, PluginInitializationState},
24 vtable::{ObjectVtable, OperationVTable, SettingVtable, ValueVTable},
25 };
26
27 use self::operation_walker::OperationHandlerRules;
28
29 pub struct State<S>(pub S);
30
31 impl<S> std::ops::Deref for State<S> {
32 type Target = S;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37 }
38
39 #[derive(Default)]
40 pub struct TypeMetadata {
41 pub objects: HashMap<&'static str, ObjectVtable>,
42 pub operations: HashMap<ObjectOperationPair<'static>, OperationVTable>,
43 pub settings: HashMap<ObjectSettingPair<'static>, SettingVtable>,
44 pub values: HashMap<ObjectValuePair<'static>, ValueVTable>,
45 }
46
47 impl TypeMetadata {
48 pub fn register_object(&mut self, object_kind: &'static str, vtable: ObjectVtable) {
49 trace!("Registering type metadata for {}", object_kind);
50
51 self.objects.insert(object_kind, vtable);
52 }
53
54 pub fn register_operation(
55 &mut self,
56 object_kind: &'static str,
57 operation_name: &'static str,
58 vtable: OperationVTable,
59 ) {
60 trace!(
61 "Registering operation metadata for {}::{}",
62 object_kind,
63 operation_name
64 );
65
66 self.operations.insert(
67 ObjectOperationPair {
68 object_kind,
69 operation_name,
70 },
71 vtable,
72 );
73 }
74
75 pub fn register_setting(
76 &mut self,
77 object_kind: &'static str,
78 setting_name: &'static str,
79 vtable: SettingVtable,
80 ) {
81 trace!("Registering setting {}::{}", object_kind, setting_name);
82
83 self.settings.insert(
84 ObjectSettingPair {
85 object_kind,
86 setting_name,
87 },
88 vtable,
89 );
90 }
91
92 pub fn register_value(
93 &mut self,
94 object_kind: &'static str,
95 value_name: &'static str,
96 vtable: ValueVTable,
97 ) {
98 trace!("Registering value {}::{}", object_kind, value_name);
99
100 self.values.insert(
101 ObjectValuePair {
102 object_kind,
103 value_name,
104 },
105 vtable,
106 );
107 }
108 }
109
110 #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
111 pub struct ObjectOperationPair<'s> {
112 pub object_kind: &'s str,
113 pub operation_name: &'s str,
114 }
115
116 impl<'s> ObjectOperationPair<'s> {
117 pub fn new(object_kind: &'s str, operation_name: &'s str) -> Self {
118 Self {
119 object_kind,
120 operation_name,
121 }
122 }
123 }
124
125 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
126 pub struct ObjectSettingPair<'s> {
127 pub object_kind: &'s str,
128 pub setting_name: &'s str,
129 }
130
131 impl<'s> ObjectSettingPair<'s> {
132 pub fn new(object_kind: &'s str, setting_name: &'s str) -> Self {
133 Self {
134 object_kind,
135 setting_name,
136 }
137 }
138 }
139
140 #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
141 pub struct ObjectValuePair<'s> {
142 pub object_kind: &'s str,
143 pub value_name: &'s str,
144 }
145
146 impl<'s> ObjectValuePair<'s> {
147 pub fn new(object_kind: &'s str, value_name: &'s str) -> Self {
148 Self {
149 object_kind,
150 value_name,
151 }
152 }
153 }
154
155 #[derive(Clone, Copy)]
156 #[repr(C)]
157 pub struct PluginState {
158 pub inner: *mut (),
159 }
160
161 impl PluginState {
162 pub unsafe fn transmute_owned<T>(&mut self) -> Box<T> {
163 Box::from_raw(self.inner as *mut T)
164 }
165
166 pub unsafe fn transmute_ref<T>(&self) -> &T {
167 let ptr: *const T = transmute(self.inner);
168
169 ptr.as_ref().unwrap()
170 }
171 }
172
173 impl PluginState {
174 pub fn null() -> Self {
175 Self { inner: null_mut() }
176 }
177 }
178
179 pub struct Runtime {
180 plugins: Vec<(PluginMeta, PluginHandle)>,
181 handlers: RuntimeHandlers,
182 }
183
184 impl Runtime {
185 pub fn new() -> Self {
186 Self {
187 plugins: vec![],
188 handlers: RuntimeHandlers::default(),
189 }
190 }
191
192 pub fn insert_plugin(&mut self, mut plugin: PluginHandle) {
193 let _guard = debug_span!("inserting plugin", meta = debug(&plugin.meta)).entered();
194
195 for (pair, callback) in &plugin.initialization.operation_handlers {
196 let _guard =
197 trace_span!("processing operation handler callbacks", pair = debug(pair)).entered();
198
199 if self
200 .handlers
201 .operation_handlers
202 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
203 .is_some()
204 {
205 warn!("Warning! Insertion of handler for overwrote a previous handler.")
206 }
207
208 trace!("Insertion of operation handler successful")
209 }
210
211 for (pair, callback) in &plugin.initialization.value_getters {
212 let _guard =
213 trace_span!("processing value getter callbacks", pair = debug(pair)).entered();
214
215 if self
216 .handlers
217 .value_getters
218 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
219 .is_some()
220 {
221 warn!("Warning! Insertion of handler for overwrote a previous handler.")
222 }
223
224 trace!("Insertion of operation handler successful")
225 }
226
227 for (pair, callback) in &plugin.initialization.setting_getters {
228 let _guard =
229 trace_span!("processing setting getter callbacks", pair = debug(pair)).entered();
230
231 if self
232 .handlers
233 .setting_getters
234 .insert(*pair, (RuntimeDomain::from_plugin(&plugin), *callback))
235 .is_some()
236 {
237 warn!("Warning! Insertion of setting handler for overwrote a previous handler.")
238 }
239
240 trace!("Insertion of setting handler successful")
241 }
242 }
243
244 pub fn handle(
245 &self,
246 object_kind: &str,
247 operation_name: &str,
248 object: &str,
249 operation_payload: &[u8],
250 ) -> Result<(), OperationError<()>> {
251 // let rules = self.handlers.handle_operation(object_kind, operation_name);
252
253 // rules.handle(object, operation_payload)
254
255 todo!()
256 }
257
258 pub fn handle_typed<O: GiteratedObject, D: GiteratedOperation<O>>(
259 &self,
260 object: O,
261 operation: D,
262 ) -> Result<D::Success, OperationError<D::Failure>> {
263 todo!()
264 }
265 }
266
267 #[derive(Default)]
268 pub struct RuntimeHandlers {
269 operation_handlers:
270 HashMap<ObjectOperationPair<'static>, (RuntimeDomain, OperationHandlerCallback)>,
271 value_getters: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueGetterCallback)>,
272 setting_getters: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingGetterCallback)>,
273 value_change: HashMap<ObjectValuePair<'static>, (RuntimeDomain, ValueChangeCallback)>,
274 setting_change: HashMap<ObjectSettingPair<'static>, (RuntimeDomain, SettingChangeCallback)>,
275 }
276
277 unsafe impl Send for RuntimeHandlers {}
278 unsafe impl Sync for RuntimeHandlers {}
279
280 impl RuntimeHandlers {
281 pub fn operation_handler(
282 &mut self,
283 pair: ObjectOperationPair<'static>,
284 handler: OperationHandlerCallback,
285 domain: RuntimeDomain,
286 ) {
287 trace!(
288 "Inserting operation handler for {}::{}",
289 pair.object_kind,
290 pair.operation_name
291 );
292
293 // There can only be one handler per operation (at least for now?), send a warning if
294 // a newly registered handler overwrites the previous handler.
295 if self
296 .operation_handlers
297 .insert(pair, (domain, handler))
298 .is_some()
299 {
300 debug!("Warning! A newly inserted operation handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.operation_name);
301 }
302 }
303
304 pub fn value_getter(
305 &mut self,
306 pair: ObjectValuePair<'static>,
307 handler: ValueGetterCallback,
308 domain: RuntimeDomain,
309 ) {
310 trace!(
311 "Inserting value getter for {}::{}",
312 pair.object_kind,
313 pair.value_name
314 );
315
316 if self.value_getters.insert(pair, (domain, handler)).is_some() {
317 debug!(
318 "Warning! A newly inserted value getter for {}::{} overwrites a previous handler.",
319 pair.object_kind, pair.value_name
320 );
321 }
322 }
323
324 pub fn setting_getter(
325 &mut self,
326 pair: ObjectSettingPair<'static>,
327 handler: SettingGetterCallback,
328 domain: RuntimeDomain,
329 ) {
330 trace!(
331 "Inserting setting getter for {}::{}",
332 pair.object_kind,
333 pair.setting_name
334 );
335
336 if self
337 .setting_getters
338 .insert(pair, (domain, handler))
339 .is_some()
340 {
341 debug!("Warning! A newly inserted setting getter for {}::{} overwrites a previous handler.", pair.object_kind, pair.setting_name);
342 }
343 }
344
345 pub fn value_change(
346 &mut self,
347 pair: ObjectValuePair<'static>,
348 handler: ValueChangeCallback,
349 domain: RuntimeDomain,
350 ) {
351 trace!(
352 "Inserting value change handler for {}::{}",
353 pair.object_kind,
354 pair.value_name
355 );
356
357 if self.value_change.insert(pair, (domain, handler)).is_some() {
358 debug!("Warning! A newly inserted value change handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.value_name);
359 panic!("Not intended");
360 }
361 }
362
363 pub fn setting_change(
364 &mut self,
365 pair: ObjectSettingPair<'static>,
366 handler: SettingChangeCallback,
367 domain: RuntimeDomain,
368 ) {
369 trace!(
370 "Inserting setting change handler for {}::{}",
371 pair.object_kind,
372 pair.setting_name
373 );
374
375 if self
376 .setting_change
377 .insert(pair, (domain, handler))
378 .is_some()
379 {
380 debug!("Warning! A newly inserted setting change handler for {}::{} overwrites a previous handler.", pair.object_kind, pair.setting_name);
381 panic!("Not intended");
382 }
383 }
384 }
385
386 impl RuntimeHandlers {
387 pub fn handle_operation<'o>(
388 &'o self,
389 object_kind: &'o str,
390 operation_name: &'o str,
391 ) -> OperationHandlerRules<'o> {
392 OperationHandlerRules::new(object_kind, operation_name, self)
393 }
394 }
395
396 pub struct RuntimeDomain {
397 plugin: PluginHandle,
398 }
399
400 impl RuntimeDomain {
401 pub fn from_plugin(plugin: &PluginHandle) -> Self {
402 Self {
403 plugin: plugin.clone(),
404 }
405 }
406
407 pub fn object_vtable(&self, object_kind: &str) -> Option<ObjectVtable> {
408 self.plugin
409 .initialization
410 .type_metadata
411 .objects
412 .get(object_kind)
413 .copied()
414 }
415
416 pub fn operation_vtable(
417 &self,
418 object_kind: &str,
419 operation_name: &str,
420 ) -> Option<OperationVTable> {
421 self.plugin
422 .initialization
423 .type_metadata
424 .operations
425 .get(&ObjectOperationPair::new(object_kind, operation_name))
426 .copied()
427 }
428
429 pub fn setting_vtable(&self, object_kind: &str, setting_name: &str) -> Option<SettingVtable> {
430 self.plugin
431 .initialization
432 .type_metadata
433 .settings
434 .get(&ObjectSettingPair::new(object_kind, setting_name))
435 .copied()
436 }
437
438 pub fn value_vtable(&self, object_kind: &str, value_name: &str) -> Option<ValueVTable> {
439 self.plugin
440 .initialization
441 .type_metadata
442 .values
443 .get(&ObjectValuePair::new(object_kind, value_name))
444 .copied()
445 }
446 }
447
448 #[derive(Clone, Debug)]
449 pub struct PluginMeta {
450 pub name: String,
451 pub version: Version,
452 }
453
454 #[repr(C)]
455 pub struct FFIPluginMeta {
456 pub name: *const u8,
457 pub name_len: usize,
458 pub version: *const u8,
459 pub version_len: usize,
460 }
461
462 pub struct RuntimePlugin {
463 handle: PluginHandle,
464 type_metadata: Arc<TypeMetadata>,
465 }
466
467 impl RuntimePlugin {
468 pub fn plugin_meta(&self) -> PluginMeta {
469 let meta = unsafe { self.handle.raw.plugin_meta() };
470
471 let name = unsafe { std::slice::from_raw_parts(meta.name, meta.name_len) };
472 let version = unsafe { std::slice::from_raw_parts(meta.version, meta.version_len) };
473
474 let name = std::str::from_utf8(name).unwrap();
475 let version = std::str::from_utf8(version).unwrap();
476
477 PluginMeta {
478 name: String::from(name),
479 version: Version::parse(version).unwrap(),
480 }
481 }
482 }
483
484 pub enum HandlerError {
485 Failure(()),
486 Internal(()),
487 Unhandled,
488 }
489
490 pub trait StateId {
491 fn state_id(&self) -> &'static str;
492 }
493
494 pub unsafe trait FfiState: StateId {
495 fn into_ffi_state_bytes(self) -> Vec<u8>;
496
497 fn from_ffi_state_bytes(bytes: Vec<u8>) -> Self;
498 }
499
500 unsafe impl<T> FfiState for T
501 where
502 T: Serialize + StateId,
503 {
504 fn into_ffi_state_bytes(self) -> Vec<u8> {
505 todo!()
506 }
507
508 fn from_ffi_state_bytes(bytes: Vec<u8>) -> Self {
509 todo!()
510 }
511 }
512
513 #[derive(Clone, Debug)]
514 pub struct OperationState {
515 entries: HashMap<&'static str, Vec<u8>>,
516 }
517