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

ambee/giterated

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

Update dependencies

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨931e8eb

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