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

ambee/giterated

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

Finish unified stack refactor.

Adds support for operation state, which will be used to pass authentication information around. Added generic backend that uses a channel to communicate with a typed backend.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨d15581c

⁨giterated-stack/src/handler.rs⁩ - ⁨5515⁩ bytes
Raw
1 use giterated_models::{
2 error::OperationError,
3 object::{
4 AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse,
5 },
6 object_backend::ObjectBackend,
7 operation::{AnyOperation, GiteratedOperation},
8 };
9 use std::{fmt::Debug, str::FromStr, sync::Arc};
10 use tracing::warn;
11
12 use crate::{state::HandlerState, OperationHandlers};
13
14 use crate::StackOperationState;
15
16 #[derive(Clone)]
17 pub struct GiteratedBackend<S: HandlerState> {
18 state: S,
19 handlers: Arc<OperationHandlers<S>>,
20 }
21
22 impl<S: HandlerState> GiteratedBackend<S> {
23 pub fn new(state: S, handlers: OperationHandlers<S>) -> Self {
24 Self {
25 state,
26 handlers: Arc::new(handlers),
27 }
28 }
29
30 pub fn state(&self) -> &S {
31 &self.state
32 }
33 }
34
35 #[async_trait::async_trait]
36 impl<S: HandlerState> ObjectBackend<StackOperationState> for GiteratedBackend<S> {
37 async fn object_operation<O, D>(
38 &self,
39 object: O,
40 operation: &str,
41 payload: D,
42 operation_state: &StackOperationState,
43 ) -> Result<D::Success, OperationError<D::Failure>>
44 where
45 O: GiteratedObject + Debug,
46 D: GiteratedOperation<O> + Debug,
47 {
48 let serialized =
49 serde_json::to_value(payload).map_err(|e| OperationError::Internal(e.to_string()))?;
50 let object = object.to_string();
51
52 if operation == ObjectRequest::operation_name() {
53 // We're doing an object request
54 let raw_result = self
55 .handlers
56 .resolve_object(
57 AnyObject(object.clone()),
58 serde_json::from_value(serialized).unwrap(),
59 self.state.clone(),
60 &operation_state,
61 )
62 .await;
63
64 return match raw_result {
65 Ok(result) => Ok(serde_json::from_slice(&result)
66 .map_err(|e| OperationError::Internal(e.to_string()))?),
67 Err(err) => match err {
68 OperationError::Internal(internal) => {
69 warn!(
70 "Internal Error: {:?}",
71 OperationError::<()>::Internal(internal.clone())
72 );
73
74 Err(OperationError::Internal(internal))
75 }
76 OperationError::Unhandled => Err(OperationError::Unhandled),
77 OperationError::Operation(err) => Err(OperationError::Operation(
78 serde_json::from_slice(&err)
79 .map_err(|e| OperationError::Internal(e.to_string()))?,
80 )),
81 },
82 };
83 }
84
85 let raw_result = self
86 .handlers
87 .handle(
88 &AnyObject(object),
89 operation,
90 AnyOperation(serialized),
91 self.state.clone(),
92 &operation_state,
93 )
94 .await;
95
96 match raw_result {
97 Ok(result) => Ok(serde_json::from_slice(&result)
98 .map_err(|e| OperationError::Internal(e.to_string()))?),
99 Err(err) => match err {
100 OperationError::Internal(internal) => {
101 warn!(
102 "Internal Error: {:?}",
103 OperationError::<()>::Internal(internal.clone())
104 );
105
106 Err(OperationError::Internal(internal))
107 }
108 OperationError::Unhandled => Err(OperationError::Unhandled),
109 OperationError::Operation(err) => Err(OperationError::Operation(
110 serde_json::from_slice(&err)
111 .map_err(|e| OperationError::Internal(e.to_string()))?,
112 )),
113 },
114 }
115 }
116
117 async fn get_object<O: GiteratedObject + Debug>(
118 &self,
119 object_str: &str,
120 operation_state: &StackOperationState,
121 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
122 let raw_result = self
123 .handlers
124 .resolve_object(
125 AnyObject("giterated.dev".to_string()),
126 ObjectRequest(object_str.to_string()),
127 self.state.clone(),
128 operation_state,
129 )
130 .await;
131
132 let object: ObjectResponse = match raw_result {
133 Ok(result) => Ok(serde_json::from_slice(&result)
134 .map_err(|e| OperationError::Internal(e.to_string()))?),
135 Err(err) => match err {
136 OperationError::Internal(internal) => {
137 warn!(
138 "Internal Error: {:?}",
139 OperationError::<()>::Internal(internal.clone())
140 );
141
142 Err(OperationError::Internal(internal))
143 }
144 OperationError::Unhandled => Err(OperationError::Unhandled),
145 OperationError::Operation(err) => Err(OperationError::Operation(
146 serde_json::from_slice(&err)
147 .map_err(|e| OperationError::Internal(e.to_string()))?,
148 )),
149 },
150 }?;
151
152 unsafe {
153 Ok(Object::new_unchecked(
154 O::from_str(&object.0)
155 .map_err(|_| OperationError::Internal("deserialize failure".to_string()))?,
156 self.clone(),
157 ))
158 }
159 }
160 }
161