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

ambee/giterated

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

Match handlers by object name and operation.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨8bec189

Showing ⁨⁨1⁩ changed file⁩ with ⁨⁨77⁩ insertions⁩ and ⁨⁨43⁩ deletions⁩

giterated-stack/src/lib.rs

View file
@@ -1,7 +1,7 @@
1 1 pub mod handler;
2 2 pub mod state;
3 3
4 use std::{future::Future, pin::Pin, sync::Arc};
4 use std::{collections::HashMap, future::Future, pin::Pin, str::FromStr, sync::Arc};
5 5
6 6 use futures_util::FutureExt;
7 7 use giterated_models::{
@@ -9,17 +9,26 @@ use giterated_models::{
9 9 instance::Instance,
10 10 object::{AnyObject, GiteratedObject, ObjectRequest, ObjectResponse},
11 11 operation::{AnyOperation, GiteratedOperation},
12 repository::Repository,
13 user::User,
12 14 };
15 use tracing::info;
16
17 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
18 struct ObjectOperationPair {
19 object_name: String,
20 operation_name: String,
21 }
13 22
14 23 pub struct OperationHandlers<S: Send + Sync + Clone> {
15 operations: Vec<OperationWrapper<S>>,
24 operations: HashMap<ObjectOperationPair, OperationWrapper<S>>,
16 25 get_object: Vec<OperationWrapper<S>>,
17 26 }
18 27
19 28 impl<S: Send + Sync + Clone> Default for OperationHandlers<S> {
20 29 fn default() -> Self {
21 30 Self {
22 operations: Vec::new(),
31 operations: HashMap::new(),
23 32 get_object: Vec::new(),
24 33 }
25 34 }
@@ -34,11 +43,17 @@ impl<S: Send + Sync + Clone + 'static> OperationHandlers<S> {
34 43 &mut self,
35 44 handler: H,
36 45 ) -> &mut Self {
37 let _operation_name = handler.operation_name().to_string();
46 let object_name = handler.object_name().to_string();
47 let operation_name = handler.operation_name().to_string();
38 48
39 49 let wrapped = OperationWrapper::new(handler);
40 50
41 self.operations.push(wrapped);
51 let pair = ObjectOperationPair {
52 object_name,
53 operation_name,
54 };
55
56 assert!(self.operations.insert(pair, wrapped).is_none());
42 57
43 58 self
44 59 }
@@ -65,29 +80,42 @@ impl<S: Send + Sync + Clone + 'static> OperationHandlers<S> {
65 80 pub async fn handle<O: GiteratedObject>(
66 81 &self,
67 82 object: &O,
68 _operation_name: &str,
83 operation_name: &str,
69 84 operation: AnyOperation,
70 85 state: S,
71 86 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
72 for handler in self.operations.iter() {
73 return match handler
87 // TODO
88 let object = object.to_string();
89
90 let object_name = {
91 if User::from_str(&object).is_ok() {
92 User::object_name()
93 } else if Repository::from_str(&object).is_ok() {
94 Repository::object_name()
95 } else if Instance::from_str(&object).is_ok() {
96 Instance::object_name()
97 } else {
98 return Err(OperationError::Unhandled);
99 }
100 }
101 .to_string();
102
103 let target_handler = ObjectOperationPair {
104 object_name,
105 operation_name: operation_name.to_string(),
106 };
107
108 if let Some(handler) = self.operations.get(&target_handler) {
109 handler
74 110 .handle(
75 111 AnyObject(object.to_string()),
76 112 operation.clone(),
77 113 state.clone(),
78 114 )
79 115 .await
80 {
81 Ok(ok) => Ok(ok),
82 Err(err) => Err(match err {
83 OperationError::Operation(err) => OperationError::Operation(err),
84 OperationError::Internal(err) => OperationError::Internal(err),
85 OperationError::Unhandled => continue,
86 }),
87 };
116 } else {
117 Err(OperationError::Unhandled)
88 118 }
89
90 Err(OperationError::Unhandled)
91 119 }
92 120
93 121 pub async fn resolve_object(
@@ -166,8 +194,8 @@ where
166 194 }
167 195 }
168 196
169 pub struct OperationWrapper<S: Send + Sync + Clone>(
170 Box<
197 pub struct OperationWrapper<S: Send + Sync + Clone> {
198 func: Box<
171 199 dyn Fn(
172 200 AnyObject,
173 201 AnyOperation,
@@ -177,7 +205,8 @@ pub struct OperationWrapper<S: Send + Sync + Clone>(
177 205 + Send
178 206 + Sync,
179 207 >,
180 );
208 object_name: String,
209 }
181 210
182 211 impl<S: Send + Sync + Clone + 'static> OperationWrapper<S> {
183 212 pub fn new<
@@ -188,28 +217,33 @@ impl<S: Send + Sync + Clone + 'static> OperationWrapper<S> {
188 217 handler: F,
189 218 ) -> Self {
190 219 let handler = Arc::new(Box::pin(handler));
191 Self(Box::new(move |any_object, any_operation, state| {
192 let handler = handler.clone();
193 async move {
220 Self {
221 func: Box::new(move |any_object, any_operation, state| {
194 222 let handler = handler.clone();
195 let object: O =
196 O::from_object_str(&any_object.0).map_err(|_| OperationError::Unhandled)?;
197 let operation: D = serde_json::from_value(any_operation.0.clone())
198 .map_err(|_| OperationError::Unhandled)?;
199
200 let result = handler.handle(&object, operation, state).await;
201 result
202 .map(|success| serde_json::to_vec(&success).unwrap())
203 .map_err(|err| match err {
204 OperationError::Operation(err) => {
205 OperationError::Operation(serde_json::to_vec(&err).unwrap())
206 }
207 OperationError::Internal(internal) => OperationError::Internal(internal),
208 OperationError::Unhandled => OperationError::Unhandled,
209 })
210 }
211 .boxed()
212 }))
223 async move {
224 let handler = handler.clone();
225 let object: O =
226 O::from_object_str(&any_object.0).map_err(|_| OperationError::Unhandled)?;
227 let operation: D = serde_json::from_value(any_operation.0.clone())
228 .map_err(|_| OperationError::Unhandled)?;
229
230 let result = handler.handle(&object, operation, state).await;
231 result
232 .map(|success| serde_json::to_vec(&success).unwrap())
233 .map_err(|err| match err {
234 OperationError::Operation(err) => {
235 OperationError::Operation(serde_json::to_vec(&err).unwrap())
236 }
237 OperationError::Internal(internal) => {
238 OperationError::Internal(internal)
239 }
240 OperationError::Unhandled => OperationError::Unhandled,
241 })
242 }
243 .boxed()
244 }),
245 object_name: O::object_name().to_string(),
246 }
213 247 }
214 248
215 249 async fn handle(
@@ -218,6 +252,6 @@ impl<S: Send + Sync + Clone + 'static> OperationWrapper<S> {
218 252 operation: AnyOperation,
219 253 state: S,
220 254 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
221 self.0(object, operation, state).await
255 (self.func)(object, operation, state).await
222 256 }
223 257 }