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

ambee/giterated

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

Progress on refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c9f076f

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨6724⁩ bytes
Raw
1 use std::{collections::HashMap, pin::Pin, sync::Arc};
2
3 use futures_util::{future::BoxFuture, Future, FutureExt};
4 use giterated_models::{
5 error::{GetValueError, OperationError},
6 model::{repository::Repository, settings::AnySetting, user::User},
7 operation::{AnyObject, AnyOperation, GetValue, GiteratedObject, GiteratedOperation},
8 values::{AnyValue, GetSetting, GetSettingError, SetSetting, SetSettingError},
9 };
10
11 use super::DatabaseBackend;
12
13 #[async_trait::async_trait]
14 pub trait GiteratedOperationHandler<
15 O: GiteratedObject,
16 D: GiteratedOperation<O>,
17 S: Send + Sync + Clone,
18 >
19 {
20 fn operation_name(&self) -> &str;
21 fn object_name(&self) -> &str;
22
23 async fn handle(
24 &self,
25 object: &O,
26 operation: D,
27 state: S,
28 ) -> Result<D::Success, OperationError<D::Failure>>;
29 }
30
31 #[async_trait::async_trait]
32 impl<O, D, F, S> GiteratedOperationHandler<O, D, S> for F
33 where
34 F: FnMut(
35 &O,
36 D,
37 S,
38 ) -> Pin<
39 Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>> + Send>,
40 > + Send
41 + Sync
42 + Clone,
43 O: GiteratedObject + Send + Sync,
44 D: GiteratedOperation<O> + 'static,
45 <D as GiteratedOperation<O>>::Failure: Send,
46 S: Send + Sync + Clone + 'static,
47 {
48 fn operation_name(&self) -> &str {
49 D::operation_name()
50 }
51
52 fn object_name(&self) -> &str {
53 O::object_name()
54 }
55
56 async fn handle(
57 &self,
58 object: &O,
59 operation: D,
60 state: S,
61 ) -> Result<D::Success, OperationError<D::Failure>> {
62 self.clone()(object, operation, state).await
63 }
64 }
65
66 pub struct OperationWrapper<S: Send + Sync + Clone>(
67 Box<
68 dyn Fn(
69 AnyObject,
70 AnyOperation,
71 S,
72 )
73 -> Pin<Box<dyn Future<Output = Result<Vec<u8>, OperationError<Vec<u8>>>> + Send>>
74 + Send
75 + Sync,
76 >,
77 );
78
79 impl<S: Send + Sync + Clone + 'static> OperationWrapper<S> {
80 pub fn new<
81 O: GiteratedObject + Send + Sync,
82 D: GiteratedOperation<O> + 'static,
83 F: GiteratedOperationHandler<O, D, S> + Send + Sync + 'static + Clone,
84 >(
85 handler: F,
86 ) -> Self {
87 let handler = Arc::new(Box::pin(handler));
88 Self(Box::new(move |any_object, any_operation, state| {
89 let handler = handler.clone();
90 async move {
91 let handler = handler.clone();
92 let object: O = O::from_object_str(&any_object.0).unwrap();
93 let operation: D = serde_json::from_value(any_operation.0.clone()).unwrap();
94
95 let result = handler.handle(&object, operation, state).await;
96 result
97 .map(|success| serde_json::to_vec(&success).unwrap())
98 .map_err(|err| match err {
99 OperationError::Operation(err) => {
100 OperationError::Operation(serde_json::to_vec(&err).unwrap())
101 }
102 OperationError::Internal(internal) => OperationError::Internal(internal),
103 OperationError::Unhandled => OperationError::Unhandled,
104 })
105 }
106 .boxed()
107 }))
108 }
109
110 async fn handle(
111 &mut self,
112 object: AnyObject,
113 operation: AnyOperation,
114 state: S,
115 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
116 self.0(object, operation, state).await
117 }
118 }
119
120 fn test_operation(
121 _object: &User,
122 _operation: SetSetting<AnySetting>,
123 _state: (),
124 ) -> Pin<Box<dyn Future<Output = Result<(), OperationError<SetSettingError>>> + Send + 'static>> {
125 todo!()
126 }
127
128 fn foo() {}
129
130 pub fn user_get_value(
131 object: &User,
132 operation: GetValue<AnyValue<User>>,
133 state: DatabaseBackend,
134 ) -> BoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
135 let object = object.clone();
136
137 async move {
138 let mut user_backend = state.user_backend.lock().await;
139 let value = user_backend
140 .get_value(&object, &operation.value_name)
141 .await
142 .map_err(|e| OperationError::Internal(e.to_string()))?;
143
144 Ok(value)
145 }
146 .boxed()
147 }
148
149 pub fn user_get_setting(
150 _object: &User,
151 _operation: GetSetting<AnySetting>,
152 _state: DatabaseBackend,
153 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
154 todo!()
155 }
156
157 pub fn user_set_setting(
158 _object: &User,
159 _operation: SetSetting<AnySetting>,
160 _state: DatabaseBackend,
161 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
162 todo!()
163 }
164
165 pub fn repository_get_value(
166 _object: &Repository,
167 _operation: GetValue<AnyValue<Repository>>,
168 _state: DatabaseBackend,
169 ) -> BoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
170 todo!()
171 }
172
173 pub fn repository_get_setting(
174 _object: &Repository,
175 _operation: GetSetting<AnySetting>,
176 _state: DatabaseBackend,
177 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
178 todo!()
179 }
180
181 pub fn repository_set_setting(
182 _object: &Repository,
183 _operation: SetSetting<AnySetting>,
184 _state: DatabaseBackend,
185 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
186 todo!()
187 }
188
189 pub struct OperationHandlers<S: Send + Sync + Clone> {
190 operations: HashMap<String, OperationWrapper<S>>,
191 }
192
193 impl<S: Send + Sync + Clone> Default for OperationHandlers<S> {
194 fn default() -> Self {
195 Self {
196 operations: HashMap::new(),
197 }
198 }
199 }
200
201 impl<S: Send + Sync + Clone + 'static> OperationHandlers<S> {
202 pub fn insert<
203 O: GiteratedObject + Send + Sync,
204 D: GiteratedOperation<O> + 'static,
205 H: GiteratedOperationHandler<O, D, S> + Send + Sync + 'static + Clone,
206 >(
207 &mut self,
208 handler: H,
209 ) -> &mut Self {
210 let operation_name = handler.operation_name().to_string();
211
212 let wrapped = OperationWrapper::new(handler);
213
214 self.operations.insert(operation_name, wrapped);
215
216 self
217 }
218
219 pub async fn handle<O: GiteratedObject>(
220 &mut self,
221 object: &O,
222 operation_name: &str,
223 operation: AnyOperation,
224 state: S,
225 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
226 if let Some(handler) = self.operations.get_mut(operation_name) {
227 handler
228 .handle(
229 AnyObject(serde_json::to_string(object).unwrap()),
230 operation,
231 state,
232 )
233 .await
234 } else {
235 panic!()
236 }
237 }
238 }
239