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

ambee/giterated

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

Merge branch dyn_inherent into master

This is a squashed commit of the following: commit 6b7c04bc1aae470d9c95b9c5f4e5698bd8c8fef0 Author: Amber <[email protected]> Date: Tue Sep 26 14:03:52 2023 -0500 Give meta types better ergonomics and location

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨f94279e

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