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

ambee/giterated

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

Beginning of `stack-next` refactor

-Refactoring the protocol stack into something similar to a runtime. -Handles merging handler builders which is placing the ground work for plugins in. - Increased metadata generation during compilation enables less ser/de during execution. - Goal is to have an O(1) time from incoming operation to calling handlers. - Decreased penalty for using the statically typed API from within your code, now avoids some allocation. # Changes - Added `GiteratedRuntime` which is to replace the current unified stack - Added `RuntimeBuilder` which does what the current `OperationHandlers` struct does, but much better. - Added `RuntimeMetadata` to store type metadata for new `Any` based internals - Refactored serde_json out of the internal operation handling

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨708dea4

⁨giterated-stack/src/update.rs⁩ - ⁨5411⁩ bytes
Raw
1 use std::sync::Arc;
2
3 use futures_util::{future::BoxFuture, FutureExt};
4 use giterated_models::{
5 object::GiteratedObject,
6 settings::{AnySetting, Setting},
7 value::{AnyValue, GiteratedObjectValue},
8 };
9
10 use crate::StackOperationState;
11
12 #[async_trait::async_trait]
13 pub trait HandleValueUpdate<O, V: GiteratedObjectValue<Object = O>> {
14 async fn handle_value_update(
15 &mut self,
16 object: O,
17 value_name: String,
18 value: V,
19 operation_state: &StackOperationState,
20 ) -> Result<(), ()>;
21 }
22
23 #[async_trait::async_trait]
24 impl<F, O, V> HandleValueUpdate<O, V> for F
25 where
26 F: Fn(O, String, V, &StackOperationState) -> BoxFuture<'static, Result<(), ()>> + Send + Sync,
27 O: GiteratedObject + Send + Sync + 'static,
28 V: GiteratedObjectValue<Object = O> + Send + Sync + 'static,
29 {
30 async fn handle_value_update(
31 &mut self,
32 object: O,
33 value_name: String,
34 value: V,
35 operation_state: &StackOperationState,
36 ) -> Result<(), ()> {
37 self(object, value_name, value, operation_state).await
38 }
39 }
40
41 #[async_trait::async_trait]
42 pub trait HandleSettingUpdate<O, S: Setting> {
43 async fn handle_setting_update(
44 &mut self,
45 object: O,
46 setting_name: String,
47 setting: S,
48 operation_state: &StackOperationState,
49 ) -> Result<(), ()>;
50 }
51
52 #[async_trait::async_trait]
53 impl<F, O, S> HandleSettingUpdate<O, S> for F
54 where
55 F: Fn(O, String, S, &StackOperationState) -> BoxFuture<'static, Result<(), ()>> + Send + Sync,
56 O: GiteratedObject + Send + Sync + 'static,
57 S: Setting + Send + Sync + 'static,
58 {
59 async fn handle_setting_update(
60 &mut self,
61 object: O,
62 setting_name: String,
63 setting: S,
64 operation_state: &StackOperationState,
65 ) -> Result<(), ()> {
66 self(object, setting_name, setting, operation_state).await
67 }
68 }
69
70 #[async_trait::async_trait]
71 pub trait ValueUpdatedHandler<O> {
72 async fn value_updated(&mut self, object: &O, value_name: &str, value: AnyValue<()>);
73 }
74
75 #[async_trait::async_trait]
76 pub trait SettingUpdatedHandler<O> {
77 async fn setting_updated(&mut self, object: &O, setting_name: &str, setting: AnySetting);
78 }
79
80 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
81 pub struct ValueUpdateKind {
82 pub object_kind: String,
83 pub value_name: String,
84 }
85
86 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
87 pub struct SettingUpdateKind {
88 pub object_kind: String,
89 pub setting_name: String,
90 }
91
92 pub struct HandleSettingUpdatedFunction {
93 pub target: SettingUpdateKind,
94 pub function: Box<
95 dyn FnOnce(
96 String,
97 String,
98 AnySetting,
99 StackOperationState,
100 ) -> BoxFuture<'static, Result<(), ()>>
101 + Send
102 + Sync,
103 >,
104 }
105
106 impl HandleSettingUpdatedFunction {
107 pub fn new<
108 S: Setting + Send + Sync,
109 T: HandleSettingUpdate<O, S> + 'static + Clone + Send + Sync,
110 O: GiteratedObject + Send + Sync,
111 >(
112 handler: T,
113 setting_name: &str,
114 ) -> Self {
115 Self {
116 target: SettingUpdateKind {
117 object_kind: O::object_name().to_string(),
118 setting_name: setting_name.to_string(),
119 },
120
121 function: Box::new(move |object, setting_name, value, state| {
122 async move {
123 let mut handler = handler;
124
125 let object = match O::from_str(&object) {
126 Ok(object) => object,
127 Err(_) => return Err(()),
128 };
129
130 let setting: S = serde_json::from_value(value.0).unwrap();
131
132 handler
133 .handle_setting_update(object, setting_name, setting, &state)
134 .await;
135
136 Ok(())
137 }
138 .boxed()
139 }),
140 }
141 }
142 }
143
144 pub struct HandleValueUpdatedFunction {
145 pub target: ValueUpdateKind,
146 pub function: Box<
147 dyn FnOnce(
148 String,
149 String,
150 AnySetting,
151 StackOperationState,
152 ) -> BoxFuture<'static, Result<(), ()>>
153 + Send
154 + Sync,
155 >,
156 }
157
158 impl HandleValueUpdatedFunction {
159 pub fn new<
160 V: GiteratedObjectValue<Object = O> + Send + Sync,
161 T: HandleValueUpdate<O, V> + 'static + Clone + Send + Sync,
162 O: GiteratedObject + Send + Sync,
163 >(
164 handler: T,
165 value_name: &str,
166 ) -> Self {
167 Self {
168 target: ValueUpdateKind {
169 object_kind: O::object_name().to_string(),
170 value_name: value_name.to_string(),
171 },
172
173 function: Box::new(move |object, setting_name, value, state| {
174 async move {
175 let mut handler = handler;
176
177 let object = match O::from_str(&object) {
178 Ok(object) => object,
179 Err(_) => return Err(()),
180 };
181
182 let setting: V = serde_json::from_value(value.0).unwrap();
183
184 handler
185 .handle_value_update(object, setting_name, setting, &state)
186 .await;
187
188 Ok(())
189 }
190 .boxed()
191 }),
192 }
193 }
194 }
195