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/callback/operation.rs⁩ - ⁨5190⁩ bytes
Raw
1 use giterated_models::{
2 error::OperationError, object::GiteratedObject, operation::GiteratedOperation,
3 value::GiteratedObjectValue,
4 };
5
6 use crate::{
7 new_stack::{handle::RuntimeHandle, OperationState, PluginState, Runtime, State},
8 AnyObject, AnyOperation,
9 };
10
11 use std::{any::type_name, fmt::Debug, future::Future, sync::Arc};
12
13 use super::{CallbackPtr, RuntimeState};
14
15 #[derive(Clone, Copy)]
16 pub struct OperationHandlerCallback {
17 pub callback_ptr: CallbackPtr,
18 pub func: unsafe extern "C" fn(
19 CallbackPtr,
20 &RuntimeState,
21 &PluginState,
22 object: AnyObject,
23 operation: AnyOperation,
24 ),
25 }
26
27 impl OperationHandlerCallback {
28 pub fn new<
29 S,
30 O: GiteratedObject,
31 D: GiteratedOperation<O>,
32 A,
33 T: IntoPluginOperationHandler<S, O, D, A>,
34 >(
35 handler: T,
36 ) -> Self {
37 OperationHandlerCallback {
38 func: T::handle,
39 callback_ptr: T::callback_ptr(&handler),
40 }
41 }
42 }
43
44 pub trait IntoPluginOperationHandler<S, O: GiteratedObject, D: GiteratedOperation<O>, A> {
45 unsafe extern "C" fn handle(
46 callback_ptr: CallbackPtr,
47 runtime_state: &RuntimeState,
48 state: &PluginState,
49 object: AnyObject,
50 operation: AnyOperation,
51 );
52 fn callback_ptr(&self) -> CallbackPtr;
53 }
54
55 impl<F, S, O, D, Fut> IntoPluginOperationHandler<S, O, D, ()> for F
56 where
57 Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>,
58 F: Fn(S, O, D) -> Fut,
59 S: Clone + Debug,
60 O: Debug + GiteratedObject,
61 D: Debug + GiteratedOperation<O>,
62 {
63 unsafe extern "C" fn handle(
64 callback: CallbackPtr,
65 runtime_state: &RuntimeState,
66 state: &PluginState,
67 mut object: AnyObject,
68 mut operation: AnyOperation,
69 ) {
70 let _guard = trace_span!(
71 "operation handler",
72 object = type_name::<O>(),
73 operation = type_name::<D>()
74 )
75 .entered();
76 let state = unsafe { state.transmute_ref::<S>() };
77
78 // Since this is Rust code, we know that the AnyObject and AnyOperation are just boxes
79 let object = unsafe { object.transmute_owned::<O>() };
80 let operation = unsafe { operation.transmute_owned::<D>() };
81
82 // Cast the callback ptr to ourselves
83 let callback: *const F = std::mem::transmute(callback.0);
84 let callback = callback.as_ref().unwrap();
85
86 // callback(state.clone(), *object, *operation)
87
88 todo!()
89 }
90
91 fn callback_ptr(&self) -> CallbackPtr {
92 unsafe { CallbackPtr::from_raw(self as *const _ as *const ()) }
93 }
94 }
95
96 impl<F, S, O, D, Fut, A1> IntoPluginOperationHandler<S, O, D, (A1,)> for F
97 where
98 Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>,
99 F: Fn(S, O, D, A1) -> Fut,
100 S: Clone + Debug,
101 O: Debug + GiteratedObject,
102 D: Debug + GiteratedOperation<O>,
103 {
104 unsafe extern "C" fn handle(
105 callback_ptr: CallbackPtr,
106 runtime_state: &RuntimeState,
107 state: &PluginState,
108 object: AnyObject,
109 operation: AnyOperation,
110 ) {
111 todo!()
112 }
113
114 fn callback_ptr(&self) -> CallbackPtr {
115 todo!()
116 }
117 }
118
119 impl<F, S, O, D, Fut, A1, A2> IntoPluginOperationHandler<S, O, D, (A1, A2)> for F
120 where
121 Fut: Future<Output = Result<D::Success, OperationError<D::Failure>>>,
122 F: Fn(S, O, D, A1, A2) -> Fut,
123 S: Clone + Debug,
124 O: Debug + GiteratedObject,
125 D: Debug + GiteratedOperation<O>,
126 {
127 unsafe extern "C" fn handle(
128 callback_ptr: CallbackPtr,
129 runtime_state: &RuntimeState,
130 state: &PluginState,
131 object: AnyObject,
132 operation: AnyOperation,
133 ) {
134 todo!()
135 }
136
137 fn callback_ptr(&self) -> CallbackPtr {
138 todo!()
139 }
140 }
141
142 pub trait FromOperationState<O, D>: Sized {
143 fn from_operation_state(
144 operation_state: &OperationState,
145 runtime_state: &RuntimeState,
146 object: &O,
147 operation: &D,
148 ) -> Result<Self, OperationError<anyhow::Error>>;
149 }
150
151 impl<O, D> FromOperationState<O, D> for RuntimeHandle {
152 fn from_operation_state(
153 operation_state: &OperationState,
154 runtime_state: &RuntimeState,
155 object: &O,
156 operation: &D,
157 ) -> Result<Self, OperationError<anyhow::Error>> {
158 Ok(unsafe { RuntimeHandle::from_vtable(runtime_state.vtable) })
159 }
160 }
161
162 impl<O, D, T> FromOperationState<O, D> for Option<T>
163 where
164 T: FromOperationState<O, D>,
165 {
166 fn from_operation_state(
167 operation_state: &OperationState,
168 runtime_state: &RuntimeState,
169 object: &O,
170 operation: &D,
171 ) -> Result<Self, OperationError<anyhow::Error>> {
172 Ok(T::from_operation_state(operation_state, runtime_state, object, operation).ok())
173 }
174 }
175
176 impl<O, D, OS: Clone> FromOperationState<O, D> for State<OS> {
177 fn from_operation_state(
178 operation_state: &OperationState,
179 runtime_state: &RuntimeState,
180 object: &O,
181 operation: &D,
182 ) -> Result<Self, OperationError<anyhow::Error>> {
183 Ok(unsafe { State(runtime_state.operation_state.transmute_ref::<OS>().clone()) })
184 }
185 }
186