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

ambee/giterated

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

The long awaited, exhalted huge networking stack change.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨21b6a72

⁨giterated-stack/src/handler/mod.rs⁩ - ⁨7635⁩ bytes
Raw
1 use std::{any::Any, sync::Arc};
2 pub mod handler_impl;
3 use futures_util::{future::LocalBoxFuture, Future, FutureExt};
4 use giterated_models::error::OperationError;
5
6 use crate::{
7 AuthenticatedInstance, AuthenticatedUser, GiteratedStack, MissingValue, StackOperationState,
8 };
9
10 #[async_trait::async_trait(?Send)]
11 pub trait IntoGiteratedHandler<Params, AdditionalParams, State, OState, Output>
12 where
13 // Output cannot have non-static references
14 Output: 'static,
15 {
16 type Future: Future<Output = Output>;
17
18 async fn handle(&self, parameters: Params, state: State, operation_state: OState) -> Output;
19 }
20
21 pub struct HandlerTree<Kind> {
22 elements: Vec<Kind>,
23 }
24
25 impl<Kind> Default for HandlerTree<Kind> {
26 fn default() -> Self {
27 Self {
28 elements: Default::default(),
29 }
30 }
31 }
32
33 impl<'fut: 'o + 'p, 'p, 'o, P, O, E, OS> HandlerTree<HandlerWrapper<P, O, E, OS>>
34 where
35 P: Clone,
36 {
37 pub fn push(&mut self, handler: HandlerWrapper<P, O, E, OS>) {
38 self.elements.push(handler);
39 }
40 pub async fn handle(&self, parameters: P, operation_state: OS) -> Result<O, OperationError<E>>
41 where
42 OS: Clone + 'static,
43 {
44 for handler in self.elements.iter() {
45 match handler
46 .handle(parameters.clone(), operation_state.clone())
47 .await
48 {
49 Ok(handled) => return Ok(handled),
50 Err(err) => match err {
51 OperationError::Internal(err) => return Err(OperationError::Internal(err)),
52 OperationError::Operation(err) => return Err(OperationError::Operation(err)),
53 OperationError::Unhandled => continue,
54 },
55 }
56 }
57
58 Err(OperationError::Unhandled)
59 }
60 }
61
62 pub struct HandlerWrapper<P, O, E, OS> {
63 func: Arc<
64 dyn Fn(
65 P,
66 Arc<dyn Any + Send + Sync>,
67 OS,
68 ) -> LocalBoxFuture<'static, Result<O, OperationError<E>>>
69 + Send
70 + Sync,
71 >,
72 state: Arc<dyn Any + Send + Sync>,
73 }
74
75 impl<P, O, E, OS: 'static> HandlerWrapper<P, O, E, OS> {
76 pub fn new<S, F, A>(state: S, handler: F) -> Self
77 where
78 F: IntoGiteratedHandler<P, A, S, OS, Result<O, OperationError<E>>> + Send + Sync,
79 S: Send + Sync + Clone + 'static,
80 E: 'static,
81 P: 'static + Clone,
82 F: 'static,
83 O: 'static,
84 OS: Clone,
85 {
86 let state = Arc::new(state);
87
88 let handler_func = Arc::new(handler);
89 let state_two = state.clone();
90 HandlerWrapper {
91 func: Arc::new(
92 move |args: P, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
93 let handler = handler_func.clone();
94 let operation_state = operation_state.clone();
95 let state = state.downcast_ref::<S>().unwrap();
96 let state = state.clone();
97 async move {
98 let handler = handler.clone();
99 let operation_state = operation_state;
100 handler.handle(args, state, operation_state).await
101 }
102 .boxed_local()
103 },
104 ),
105 state: state_two,
106 }
107 }
108
109 pub async fn handle(&self, required: P, operation_state: OS) -> Result<O, OperationError<E>> {
110 (self.func)(required, self.state.clone(), operation_state).await
111 }
112
113 pub fn map<F, N, R>(self, predicate: F) -> HandlerWrapper<N, O, R, OS>
114 where
115 F: Fn(&N, &OS) -> Result<P, OperationError<R>> + Clone + Send + Sync,
116 R: std::fmt::Debug + 'static,
117 E: Into<OperationError<R>> + 'static,
118 OperationError<R>: From<OperationError<E>> + 'static,
119 F: 'static,
120 N: 'static,
121 P: 'static,
122 O: 'static,
123 OS: Clone,
124 {
125 let func = Arc::new(self.func);
126 let predicate = Arc::new(predicate);
127 HandlerWrapper {
128 func: Arc::new(
129 move |args: N, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
130 let predicate_output = predicate(&args, &operation_state);
131 let func = func.clone();
132 let operation_state: OS = operation_state.clone();
133 async move {
134 let predicate_output = predicate_output?;
135 let operation_state = operation_state;
136 match (func)(predicate_output, state, operation_state).await {
137 Ok(success) => Ok(success),
138 Err(err) => Err(err.into()),
139 }
140 }
141 .boxed_local()
142 },
143 ),
144 state: self.state,
145 }
146 }
147
148 pub fn map_return<F, NR, NE>(self, predicate: F) -> HandlerWrapper<P, NR, NE, OS>
149 where
150 F: Fn(Result<O, OperationError<E>>, &OS) -> Result<NR, OperationError<NE>>
151 + Clone
152 + Send
153 + Sync,
154 O: 'static,
155 F: 'static,
156 E: 'static,
157 P: 'static,
158 OS: Clone,
159 {
160 let predicate = Arc::new(predicate);
161 let func = self.func;
162 HandlerWrapper {
163 func: Arc::new(
164 move |args: P, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
165 let clone = predicate.clone();
166 let func = func.clone();
167 let _statoperation_statee = operation_state.clone();
168
169 async move {
170 let func = func.clone();
171 let clone = clone;
172 let operation_state = operation_state;
173 clone(
174 (func)(args, state, operation_state.clone()).await,
175 &operation_state,
176 )
177 }
178 .boxed_local()
179 },
180 ),
181 state: self.state,
182 }
183 }
184 }
185
186 #[async_trait::async_trait(?Send)]
187 pub trait HandlerResolvable<RequiredParameters, OperationState>: Sized {
188 type Error;
189
190 async fn from_handler_state(
191 required_parameters: &RequiredParameters,
192 operation_state: &OperationState,
193 ) -> Result<Self, Self::Error>;
194 }
195
196 #[async_trait::async_trait(?Send)]
197 impl<R> HandlerResolvable<R, StackOperationState> for GiteratedStack<StackOperationState> {
198 type Error = MissingValue;
199
200 async fn from_handler_state(
201 _required_parameters: &R,
202 operation_state: &StackOperationState,
203 ) -> Result<Self, Self::Error> {
204 Ok(operation_state.runtime.clone())
205 }
206 }
207
208 #[async_trait::async_trait(?Send)]
209 impl<R> HandlerResolvable<R, StackOperationState> for AuthenticatedUser {
210 type Error = MissingValue;
211
212 async fn from_handler_state(
213 _required_parameters: &R,
214 operation_state: &StackOperationState,
215 ) -> Result<Self, Self::Error> {
216 operation_state
217 .user
218 .clone()
219 .ok_or_else(|| MissingValue("AuthenticatedUser"))
220 }
221 }
222
223 #[async_trait::async_trait(?Send)]
224 impl<R> HandlerResolvable<R, StackOperationState> for AuthenticatedInstance {
225 type Error = MissingValue;
226
227 async fn from_handler_state(
228 _required_parameters: &R,
229 operation_state: &StackOperationState,
230 ) -> Result<Self, Self::Error> {
231 operation_state
232 .instance
233 .clone()
234 .ok_or_else(|| MissingValue("AuthenticatedInstance"))
235 }
236 }
237