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

ambee/giterated

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

Begin new protocol refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨26651b1

⁨giterated-daemon/src/database_backend/mod.rs⁩ - ⁨3682⁩ bytes
Raw
1 use std::{str::FromStr, sync::Arc};
2
3 use giterated_models::{
4 error::OperationError,
5 model::{instance::Instance, repository::Repository, user::User},
6 operation::{GiteratedObject, GiteratedOperation, Object, ObjectBackend, ObjectRequestError},
7 };
8 use sqlx::PgPool;
9 use std::fmt::Debug;
10 use tokio::sync::Mutex;
11
12 use crate::backend::{RepositoryBackend, UserBackend};
13
14 #[derive(Clone, Debug)]
15 pub struct Foobackend {}
16
17 #[async_trait::async_trait]
18 impl ObjectBackend for Foobackend {
19 async fn object_operation<O: GiteratedObject + Debug, D: GiteratedOperation<O> + Debug>(
20 &self,
21 _object: O,
22 _operation: D,
23 ) -> Result<D::Success, OperationError<D::Failure>> {
24 // We don't handle operations with this backend
25 Err(OperationError::Unhandled)
26 }
27
28 async fn get_object<O: GiteratedObject + Debug>(
29 &self,
30 _object_str: &str,
31 ) -> Result<Object<O, Self>, OperationError<ObjectRequestError>> {
32 todo!()
33 }
34 }
35
36 /// A backend implementation which attempts to resolve data from the instance's database.
37 #[derive(Clone)]
38 pub struct DatabaseBackend<'b> {
39 our_instance: Object<'b, Instance, Foobackend>,
40 user_backend: Arc<Mutex<dyn UserBackend + Send>>,
41 repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>>,
42 pool: PgPool,
43 }
44
45 impl Debug for DatabaseBackend<'_> {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 f.debug_struct("DatabaseBackend").finish()
48 }
49 }
50
51 #[async_trait::async_trait]
52 impl<'b> ObjectBackend for DatabaseBackend<'b> {
53 async fn object_operation<O: GiteratedObject + Debug, D: GiteratedOperation<O> + Debug>(
54 &self,
55 _object: O,
56 _operation: D,
57 ) -> Result<D::Success, OperationError<D::Failure>> {
58 // We don't handle operations with this backend
59 Err(OperationError::Unhandled)
60 }
61
62 async fn get_object<O: GiteratedObject + Debug>(
63 &self,
64 object_str: &str,
65 ) -> Result<Object<O, Self>, OperationError<ObjectRequestError>> {
66 if let Ok(user) = User::from_str(object_str) {
67 let mut user_backend = self.user_backend.lock().await;
68
69 if user_backend
70 .exists(&user)
71 .await
72 .map_err(|e| OperationError::Internal(e.to_string()))?
73 {
74 Ok(unsafe {
75 Object::new_unchecked(
76 O::from_object_str(object_str)
77 .map_err(|e| ObjectRequestError::Deserialization(e.to_string()))?,
78 self.clone(),
79 )
80 })
81 } else {
82 return Err(OperationError::Unhandled);
83 }
84 } else if let Ok(repository) = Repository::from_str(object_str) {
85 let mut repository_backend = self.repository_backend.lock().await;
86
87 if repository_backend
88 .exists(&repository)
89 .await
90 .map_err(|e| OperationError::Internal(e.to_string()))?
91 {
92 Ok(unsafe {
93 Object::new_unchecked(
94 O::from_object_str(object_str)
95 .map_err(|e| ObjectRequestError::Deserialization(e.to_string()))?,
96 self.clone(),
97 )
98 })
99 } else {
100 return Err(OperationError::Unhandled);
101 }
102 } else if Instance::from_str(object_str).is_ok() {
103 return Err(OperationError::Unhandled);
104 } else {
105 // Invalid object type
106 return Err(OperationError::Unhandled);
107 }
108 }
109 }
110