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

ambee/giterated

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

Unified stack `GetValue` implementation

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨325f5af

⁨giterated-stack/src/lib.rs⁩ - ⁨20377⁩ bytes
Raw
1 mod handler;
2 pub use handler::{GiteratedStack, GiteratedStackState, *};
3
4 pub mod state;
5 pub mod update;
6
7 use std::{any::Any, future::Future, ops::Deref, pin::Pin, sync::Arc};
8
9 use core::fmt::Debug;
10 use futures_util::FutureExt;
11 use giterated_models::{
12 error::OperationError,
13 instance::{
14 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
15 },
16 object::GiteratedObject,
17 object_backend::ObjectBackend,
18 operation::GiteratedOperation,
19 repository::{AccessList, Repository},
20 settings::{GetSetting, SetSetting},
21 user::User,
22 value::GetValue,
23 };
24 use serde::{de::DeserializeOwned, Serialize};
25
26 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
27 struct ObjectOperationPair {
28 pub object_name: String,
29 pub operation_name: String,
30 }
31
32 pub struct SettingMeta {
33 pub name: String,
34 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
35 }
36
37 pub struct ValueMeta {
38 pub name: String,
39 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
40 pub serialize:
41 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
42 pub typed_get: Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
43 pub is_get_value_typed: Box<dyn Fn(&Box<dyn Any + Send + Sync>) -> bool + Send + Sync>,
44 }
45
46 pub struct ObjectMeta {
47 pub name: String,
48 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
49 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
50 }
51
52 pub struct OperationMeta {
53 pub name: String,
54 pub object_kind: String,
55 pub deserialize:
56 Box<dyn Fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> + Send + Sync>,
57 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
58 pub serialize_success:
59 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
60 pub serialize_error:
61 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
62 }
63
64 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
65 pub struct ObjectValuePair {
66 pub object_kind: String,
67 pub value_kind: String,
68 }
69
70 #[async_trait::async_trait(?Send)]
71 pub trait GiteratedOperationHandler<
72 L,
73 O: GiteratedObject,
74 D: GiteratedOperation<O>,
75 S: Send + Sync + Clone,
76 >
77 {
78 fn operation_name(&self) -> &str;
79 fn object_name(&self) -> &str;
80
81 async fn handle(
82 &self,
83 object: &O,
84 operation: D,
85 state: S,
86 operation_state: &StackOperationState,
87 ) -> Result<D::Success, OperationError<D::Failure>>;
88 }
89
90 #[async_trait::async_trait(?Send)]
91 impl<O, D, F, S> GiteratedOperationHandler<(), O, D, S> for F
92 where
93 F: FnMut(
94 &O,
95 D,
96 S,
97 )
98 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
99 + Send
100 + Sync
101 + Clone,
102 O: GiteratedObject + Send + Sync,
103 D: GiteratedOperation<O> + 'static,
104 <D as GiteratedOperation<O>>::Failure: Send,
105 S: Send + Sync + Clone + 'static,
106 {
107 fn operation_name(&self) -> &str {
108 D::operation_name()
109 }
110
111 fn object_name(&self) -> &str {
112 O::object_name()
113 }
114
115 async fn handle(
116 &self,
117 object: &O,
118 operation: D,
119 state: S,
120 _operation_state: &StackOperationState,
121 ) -> Result<D::Success, OperationError<D::Failure>> {
122 self.clone()(object, operation, state).await
123 }
124 }
125
126 #[async_trait::async_trait(?Send)]
127 impl<O, O1, D, F, S> GiteratedOperationHandler<(O1,), O, D, S> for F
128 where
129 F: FnMut(
130 &O,
131 D,
132 S,
133 O1,
134 )
135 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
136 + Send
137 + Sync
138 + Clone,
139 O: GiteratedObject + Send + Sync,
140 D: GiteratedOperation<O> + 'static + Send + Sync,
141 <D as GiteratedOperation<O>>::Failure: Send,
142 S: Send + Sync + Clone + 'static,
143 O1: FromOperationState<O, D>,
144 {
145 fn operation_name(&self) -> &str {
146 D::operation_name()
147 }
148
149 fn object_name(&self) -> &str {
150 O::object_name()
151 }
152
153 async fn handle(
154 &self,
155 object: &O,
156 operation: D,
157 state: S,
158 operation_state: &StackOperationState,
159 ) -> Result<D::Success, OperationError<D::Failure>> {
160 let o1 = O1::from_state(object, &operation, operation_state)
161 .await
162 .map_err(|e| OperationError::Internal(e.to_string()))?;
163 self.clone()(object, operation, state, o1).await
164 }
165 }
166
167 #[async_trait::async_trait(?Send)]
168 impl<O, O1, O2, D, F, S> GiteratedOperationHandler<(O1, O2), O, D, S> for F
169 where
170 F: FnMut(
171 &O,
172 D,
173 S,
174 O1,
175 O2,
176 )
177 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
178 + Send
179 + Sync
180 + Clone,
181 O: GiteratedObject + Send + Sync,
182 D: GiteratedOperation<O> + 'static + Send + Sync,
183 <D as GiteratedOperation<O>>::Failure: Send,
184 S: Send + Sync + Clone + 'static,
185 O1: FromOperationState<O, D>,
186 O2: FromOperationState<O, D>,
187 {
188 fn operation_name(&self) -> &str {
189 D::operation_name()
190 }
191
192 fn object_name(&self) -> &str {
193 O::object_name()
194 }
195
196 async fn handle(
197 &self,
198 object: &O,
199 operation: D,
200 state: S,
201 operation_state: &StackOperationState,
202 ) -> Result<D::Success, OperationError<D::Failure>> {
203 let o1 = O1::from_state(object, &operation, operation_state)
204 .await
205 .map_err(|e| OperationError::Internal(e.to_string()))?;
206 let o2 = O2::from_state(object, &operation, operation_state)
207 .await
208 .map_err(|e| OperationError::Internal(e.to_string()))?;
209 self.clone()(object, operation, state, o1, o2).await
210 }
211 }
212
213 #[async_trait::async_trait(?Send)]
214 impl<O, O1, O2, O3, D, F, S> GiteratedOperationHandler<(O1, O2, O3), O, D, S> for F
215 where
216 F: FnMut(
217 &O,
218 D,
219 S,
220 O1,
221 O2,
222 O3,
223 )
224 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
225 + Send
226 + Sync
227 + Clone,
228 O: GiteratedObject + Send + Sync,
229 D: GiteratedOperation<O> + 'static + Send + Sync,
230 <D as GiteratedOperation<O>>::Failure: Send,
231 S: Send + Sync + Clone + 'static,
232 O1: FromOperationState<O, D>,
233 O2: FromOperationState<O, D>,
234 O3: FromOperationState<O, D>,
235 {
236 fn operation_name(&self) -> &str {
237 D::operation_name()
238 }
239
240 fn object_name(&self) -> &str {
241 O::object_name()
242 }
243
244 async fn handle(
245 &self,
246 object: &O,
247 operation: D,
248 state: S,
249 operation_state: &StackOperationState,
250 ) -> Result<D::Success, OperationError<D::Failure>> {
251 let o1 = O1::from_state(object, &operation, operation_state)
252 .await
253 .map_err(|e| OperationError::Internal(e.to_string()))?;
254 let o2 = O2::from_state(object, &operation, operation_state)
255 .await
256 .map_err(|e| OperationError::Internal(e.to_string()))?;
257 let o3 = O3::from_state(object, &operation, operation_state)
258 .await
259 .map_err(|e| OperationError::Internal(e.to_string()))?;
260 self.clone()(object, operation, state, o1, o2, o3).await
261 }
262 }
263
264 pub struct OperationWrapper {
265 func: Box<
266 dyn Fn(
267 &(dyn Any + Send + Sync),
268 &(dyn Any + Send + Sync),
269 &(dyn Any + Send + Sync),
270 StackOperationState,
271 ) -> Pin<
272 Box<
273 dyn Future<
274 Output = Result<
275 Box<dyn Any + Send + Sync>,
276 OperationError<Box<dyn Any + Send + Sync>>,
277 >,
278 >,
279 >,
280 > + Send
281 + Sync,
282 >,
283 state: Box<dyn Any + Send + Sync>,
284 }
285
286 impl OperationWrapper {
287 pub fn new<
288 A,
289 O: GiteratedObject + Send + Sync + 'static,
290 D: GiteratedOperation<O> + 'static + Clone,
291 F: GiteratedOperationHandler<A, O, D, S> + 'static + Send + Sync + Clone,
292 S: GiteratedStackState + 'static,
293 >(
294 handler: F,
295 state: S,
296 ) -> Self
297 where
298 D::Failure: Send + Sync,
299 D::Success: Send + Sync,
300 {
301 Self {
302 func: Box::new(move |object, operation, state, operation_state| {
303 let handler = handler.clone();
304 let state = state.downcast_ref::<S>().unwrap().clone();
305 let object: &O = object.downcast_ref().unwrap();
306 let operation: &D = operation.downcast_ref().unwrap();
307 let object = object.clone();
308 let operation = operation.clone();
309 async move {
310 let result = handler
311 .handle(&object, operation, state, &operation_state)
312 .await;
313 result
314 .map(|success| Box::new(success) as _)
315 .map_err(|err| match err {
316 OperationError::Operation(err) => {
317 OperationError::Operation(Box::new(err) as _)
318 }
319 OperationError::Internal(internal) => {
320 OperationError::Internal(internal)
321 }
322 OperationError::Unhandled => OperationError::Unhandled,
323 })
324 }
325 .boxed_local()
326 }),
327 state: Box::new(state),
328 }
329 }
330
331 async fn handle(
332 &self,
333 object: &Box<dyn Any + Send + Sync>,
334 operation: &Box<dyn Any + Send + Sync>,
335 operation_state: &StackOperationState,
336 ) -> Result<Box<dyn Any + Send + Sync>, OperationError<Box<dyn Any + Send + Sync>>> {
337 (self.func)(
338 (*object).as_ref(),
339 (*operation).as_ref(),
340 self.state.as_ref(),
341 operation_state.clone(),
342 )
343 .await
344 }
345 }
346
347 #[async_trait::async_trait(?Send)]
348 pub trait FromOperationState<O: GiteratedObject, D: GiteratedOperation<O>>: Sized + Clone {
349 type Error: Serialize + DeserializeOwned;
350
351 async fn from_state(
352 object: &O,
353 operation: &D,
354 state: &StackOperationState,
355 ) -> Result<Self, OperationError<Self::Error>>;
356 }
357
358 #[async_trait::async_trait(?Send)]
359 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
360 for Arc<GiteratedStack>
361 {
362 type Error = ();
363
364 async fn from_state(
365 _object: &O,
366 _operation: &D,
367 state: &StackOperationState,
368 ) -> Result<Self, OperationError<()>> {
369 Ok(state.runtime.clone())
370 }
371 }
372
373 #[async_trait::async_trait(?Send)]
374 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
375 for StackOperationState
376 {
377 type Error = ();
378
379 async fn from_state(
380 _object: &O,
381 _operation: &D,
382 state: &StackOperationState,
383 ) -> Result<StackOperationState, OperationError<()>> {
384 Ok(state.clone())
385 }
386 }
387
388 #[async_trait::async_trait(?Send)]
389 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
390 for AuthenticatedUser
391 {
392 type Error = ();
393
394 async fn from_state(
395 _object: &O,
396 _operation: &D,
397 state: &StackOperationState,
398 ) -> Result<AuthenticatedUser, OperationError<()>> {
399 state
400 .user
401 .clone()
402 .ok_or_else(|| OperationError::Operation(()))
403 }
404 }
405
406 #[async_trait::async_trait(?Send)]
407 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
408 for AuthenticatedInstance
409 {
410 type Error = ();
411
412 async fn from_state(
413 _object: &O,
414 _operation: &D,
415 state: &StackOperationState,
416 ) -> Result<AuthenticatedInstance, OperationError<()>> {
417 state
418 .instance
419 .clone()
420 .ok_or_else(|| OperationError::Operation(()))
421 }
422 }
423
424 #[async_trait::async_trait(?Send)]
425 impl<
426 T: FromOperationState<O, D> + Send + Sync,
427 O: GiteratedObject + Sync,
428 D: GiteratedOperation<O> + Send + Sync,
429 > FromOperationState<O, D> for Option<T>
430 {
431 type Error = ();
432
433 async fn from_state(
434 object: &O,
435 operation: &D,
436 state: &StackOperationState,
437 ) -> Result<Option<T>, OperationError<()>> {
438 Ok(T::from_state(object, operation, state).await.ok())
439 }
440 }
441
442 #[derive(Clone)]
443 pub struct AuthorizedUser(AuthenticatedUser);
444
445 #[derive(Clone)]
446 pub struct AuthorizedInstance(AuthenticatedInstance);
447
448 #[async_trait::async_trait(?Send)]
449 pub trait AuthorizedOperation<O: GiteratedObject>: GiteratedOperation<O> {
450 async fn authorize(
451 &self,
452 authorize_for: &O,
453 state: &StackOperationState,
454 ) -> Result<bool, OperationError<()>>;
455 }
456
457 #[async_trait::async_trait(?Send)]
458 impl<O: GiteratedObject + Send + Sync + Debug + 'static> AuthorizedOperation<O> for GetValue {
459 async fn authorize(
460 &self,
461 authorize_for: &O,
462 operation_state: &StackOperationState,
463 ) -> Result<bool, OperationError<()>> {
464 Ok(operation_state
465 .runtime
466 .get_object::<O>(&authorize_for.to_string(), operation_state)
467 .await
468 .is_ok())
469 }
470 }
471
472 #[async_trait::async_trait(?Send)]
473 impl AuthorizedOperation<User> for SetSetting {
474 async fn authorize(
475 &self,
476 authorize_for: &User,
477 operation_state: &StackOperationState,
478 ) -> Result<bool, OperationError<()>> {
479 let authenticated_user = operation_state
480 .user
481 .as_ref()
482 .ok_or_else(|| OperationError::Operation(()))?;
483
484 Ok(authorize_for == authenticated_user.deref())
485 }
486 }
487
488 #[async_trait::async_trait(?Send)]
489 impl AuthorizedOperation<User> for GetSetting {
490 async fn authorize(
491 &self,
492 authorize_for: &User,
493 operation_state: &StackOperationState,
494 ) -> Result<bool, OperationError<()>> {
495 let authenticated_user = operation_state
496 .user
497 .as_ref()
498 .ok_or_else(|| OperationError::Operation(()))?;
499
500 Ok(authorize_for == authenticated_user.deref())
501 }
502 }
503
504 #[async_trait::async_trait(?Send)]
505 impl AuthorizedOperation<Repository> for SetSetting {
506 async fn authorize(
507 &self,
508 authorize_for: &Repository,
509 operation_state: &StackOperationState,
510 ) -> Result<bool, OperationError<()>> {
511 let authenticated_user = operation_state
512 .user
513 .as_ref()
514 .ok_or_else(|| OperationError::Operation(()))?;
515
516 let mut object = operation_state
517 .runtime
518 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
519 .await
520 .map_err(|e| OperationError::Internal(e.to_string()))?;
521
522 let access_list = object
523 .get_setting::<AccessList>(operation_state)
524 .await
525 .map_err(|e| OperationError::Internal(e.to_string()))?;
526
527 if access_list
528 .0
529 .iter()
530 .find(|user| *user == authenticated_user.deref())
531 .is_some()
532 {
533 Ok(true)
534 } else {
535 Ok(false)
536 }
537 }
538 }
539
540 #[async_trait::async_trait(?Send)]
541 impl AuthorizedOperation<Repository> for GetSetting {
542 async fn authorize(
543 &self,
544 authorize_for: &Repository,
545 operation_state: &StackOperationState,
546 ) -> Result<bool, OperationError<()>> {
547 let authenticated_user = operation_state
548 .user
549 .as_ref()
550 .ok_or_else(|| OperationError::Operation(()))?;
551
552 let mut object = operation_state
553 .runtime
554 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
555 .await
556 .map_err(|e| OperationError::Internal(e.to_string()))?;
557
558 let access_list = object
559 .get_setting::<AccessList>(operation_state)
560 .await
561 .map_err(|e| OperationError::Internal(e.to_string()))?;
562
563 if access_list
564 .0
565 .iter()
566 .find(|user| *user == authenticated_user.deref())
567 .is_some()
568 {
569 Ok(true)
570 } else {
571 Ok(false)
572 }
573 }
574 }
575
576 #[async_trait::async_trait(?Send)]
577 impl AuthorizedOperation<Instance> for RegisterAccountRequest {
578 async fn authorize(
579 &self,
580 authorize_for: &Instance,
581 state: &StackOperationState,
582 ) -> Result<bool, OperationError<()>> {
583 if state.our_instance == *authorize_for {
584 Ok(true)
585 } else {
586 Ok(false)
587 }
588 }
589 }
590
591 #[async_trait::async_trait(?Send)]
592 impl AuthorizedOperation<Instance> for AuthenticationTokenRequest {
593 async fn authorize(
594 &self,
595 authorize_for: &Instance,
596 state: &StackOperationState,
597 ) -> Result<bool, OperationError<()>> {
598 if state.our_instance == *authorize_for {
599 Ok(true)
600 } else {
601 Ok(false)
602 }
603 }
604 }
605
606 #[async_trait::async_trait(?Send)]
607 impl AuthorizedOperation<Instance> for RepositoryCreateRequest {
608 async fn authorize(
609 &self,
610 authorize_for: &Instance,
611 state: &StackOperationState,
612 ) -> Result<bool, OperationError<()>> {
613 if state.our_instance == *authorize_for {
614 Ok(true)
615 } else {
616 Ok(false)
617 }
618 }
619 }
620
621 #[async_trait::async_trait(?Send)]
622 impl<A: AuthorizedOperation<User> + Send + Sync> FromOperationState<User, A> for AuthorizedUser {
623 type Error = ();
624
625 async fn from_state(
626 object: &User,
627 operation: &A,
628 state: &StackOperationState,
629 ) -> Result<AuthorizedUser, OperationError<()>> {
630 let authenticated = AuthenticatedUser::from_state(object, operation, state).await?;
631
632 match operation.authorize(object, state).await {
633 Ok(authorized) => {
634 assert!(authorized);
635 }
636 Err(err) => return Err(OperationError::Internal(err.to_string())),
637 };
638
639 Ok(AuthorizedUser(authenticated))
640 }
641 }
642
643 #[async_trait::async_trait(?Send)]
644 impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance, A>
645 for AuthorizedInstance
646 {
647 type Error = ();
648
649 async fn from_state(
650 object: &Instance,
651 operation: &A,
652 state: &StackOperationState,
653 ) -> Result<AuthorizedInstance, OperationError<()>> {
654 let authenticated = AuthenticatedInstance::from_state(object, operation, state).await?;
655
656 match operation.authorize(object, state).await {
657 Ok(authorized) => {
658 assert!(authorized);
659 }
660 Err(err) => return Err(OperationError::Internal(err.to_string())),
661 };
662
663 Ok(AuthorizedInstance(authenticated))
664 }
665 }
666
667 // #[async_trait::async_trait> FromOperationState for Option<T> {
668 // type Error = ();
669
670 // async fn from_state(state: &StackOperationState) -> Result<Option<T>, OperationError<()>> {
671 // Ok(T::from_state(]
672 // impl<T: FromOperationStatestate).await.ok())
673 // }
674 // }
675
676 #[derive(Clone)]
677 pub struct StackOperationState {
678 pub our_instance: Instance,
679 pub runtime: Arc<GiteratedStack>,
680 pub instance: Option<AuthenticatedInstance>,
681 pub user: Option<AuthenticatedUser>,
682 }
683
684 #[derive(Clone, Debug)]
685 pub struct AuthenticatedInstance(Instance);
686
687 impl AuthenticatedInstance {
688 pub fn new(instance: Instance) -> Self {
689 AuthenticatedInstance(instance)
690 }
691 }
692
693 impl Deref for AuthenticatedInstance {
694 type Target = Instance;
695
696 fn deref(&self) -> &Self::Target {
697 &self.0
698 }
699 }
700
701 #[derive(Clone, Debug)]
702 pub struct AuthenticatedUser(User);
703
704 impl AuthenticatedUser {
705 pub fn new(user: User) -> Self {
706 AuthenticatedUser(user)
707 }
708 }
709
710 impl Deref for AuthenticatedUser {
711 type Target = User;
712
713 fn deref(&self) -> &Self::Target {
714 &self.0
715 }
716 }
717