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

ambee/giterated

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

Major refactor to handler traits

Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Squashed commit of the following: commit 62e1ecf76ee31cda0bab4602d9d00fa0dc2f9158 Author: Amber <[email protected]> Date: Wed Oct 11 09:31:11 2023 -0500 Update commit dfd2d1b0b5d81ee3bc48f0321c6aceaa677e3b8b Author: Amber <[email protected]> Date: Wed Oct 11 09:31:07 2023 -0500 Major refactor to handler traits Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Removed dead and legacy code. I think... commit 57b4b398eff32e69f2f4b9700e42a1277a4d1055 Author: Amber <[email protected]> Date: Sun Oct 1 23:05:10 2023 -0500 New handler trait for giterated stack Refactor the old handler trait so it is more generic and can be used for specific kinds of handlers

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90c4780

⁨giterated-stack/src/meta/mod.rs⁩ - ⁨10501⁩ bytes
Raw
1 use std::{any::Any, collections::HashMap, str::FromStr, sync::Arc};
2
3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 use giterated_models::{
5 object::GiteratedObject,
6 operation::GiteratedOperation,
7 settings::Setting,
8 value::{GetValueTyped, GiteratedObjectValue},
9 };
10 use serde_json::Value;
11 use tracing::trace;
12
13 use crate::{
14 AnyFailure, AnyObject, AnyOperation, AnySetting, AnySuccess, AnyValue, GiteratedStack,
15 ObjectOperationPair, ObjectSettingPair, ObjectValuePair, StackOperationState,
16 };
17
18 /// Stores runtime metadata for all in-use Giterated protocol types.
19 #[derive(Default)]
20 pub struct RuntimeMetadata {
21 pub objects: HashMap<String, ObjectMeta>,
22 pub operations: HashMap<ObjectOperationPair<'static>, OperationMeta>,
23 pub values: HashMap<ObjectValuePair<'static>, ValueMeta>,
24 pub settings: HashMap<ObjectSettingPair<'static>, SettingMeta>,
25 }
26
27 impl RuntimeMetadata {
28 pub fn register_object<O: GiteratedObject + 'static>(&mut self) {
29 let object_name = O::object_name().to_string();
30
31 let object_meta = ObjectMeta::new::<O>();
32
33 if self.objects.insert(object_name, object_meta).is_some() {
34 trace!(
35 "Registration of object {} overwrote previous registration.",
36 O::object_name()
37 );
38 } else {
39 trace!("Registration of object {}.", O::object_name())
40 }
41 }
42
43 pub fn register_operation<O: GiteratedObject + 'static, D: GiteratedOperation<O> + 'static>(
44 &mut self,
45 ) {
46 let _object_name = O::object_name().to_string();
47 let _operation_name = D::operation_name().to_string();
48
49 if self
50 .operations
51 .insert(
52 ObjectOperationPair::from_types::<O, D>(),
53 OperationMeta::new::<O, D>(),
54 )
55 .is_some()
56 {
57 trace!(
58 "Registration of object operation {}<{}> overwrote previous registration.",
59 D::operation_name(),
60 O::object_name()
61 );
62 } else {
63 trace!(
64 "Registration of object operation {}<{}>.",
65 D::operation_name(),
66 O::object_name()
67 )
68 }
69 }
70
71 pub fn register_value<
72 O: GiteratedObject + 'static,
73 V: GiteratedObjectValue<Object = O> + 'static,
74 >(
75 &mut self,
76 ) {
77 let _object_name = O::object_name().to_string();
78 let _value_name = V::value_name().to_string();
79
80 if self
81 .values
82 .insert(ObjectValuePair::from_types::<O, V>(), ValueMeta::new::<V>())
83 .is_some()
84 {
85 trace!(
86 "Registration of value <{}>::{} overwrote previous registration.",
87 O::object_name(),
88 V::value_name()
89 );
90 } else {
91 trace!(
92 "Registration of value <{}>::{}.",
93 O::object_name(),
94 V::value_name()
95 );
96 }
97 }
98
99 pub fn register_setting<O: GiteratedObject + 'static, S: Setting + 'static + Clone>(&mut self) {
100 if self
101 .settings
102 .insert(
103 ObjectSettingPair::from_types::<O, S>(),
104 SettingMeta::new::<O, S>(),
105 )
106 .is_some()
107 {
108 trace!(
109 "Registration of setting {} overwrote previous registration.",
110 S::name()
111 );
112 } else {
113 trace!("Registration of setting {}.", S::name());
114 }
115 }
116
117 pub fn append(&mut self, other: Self) {
118 self.objects.extend(other.objects);
119 self.operations.extend(other.operations);
120 self.values.extend(other.values);
121 self.settings.extend(other.settings);
122 }
123 }
124
125 pub struct ValueMeta {
126 pub name: String,
127 pub deserialize: fn(&[u8]) -> Result<AnyValue, serde_json::Error>,
128 pub serialize: fn(AnyValue) -> Result<Vec<u8>, serde_json::Error>,
129 pub typed_get: fn() -> Box<dyn Any + Send + Sync>,
130 pub is_get_value_typed: fn(AnyOperation) -> bool,
131 }
132
133 pub trait IntoValueMeta {
134 fn name() -> String;
135 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error>;
136 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error>;
137 fn typed_get() -> Box<dyn Any + Send + Sync>;
138 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool;
139 }
140
141 impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValueMeta for V {
142 fn name() -> String {
143 V::value_name().to_string()
144 }
145
146 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error> {
147 Ok(AnyValue(Arc::new(serde_json::from_slice(buffer)?)))
148 }
149
150 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> {
151 let value = value.0.downcast_ref::<V>().unwrap();
152
153 serde_json::to_vec(&*value)
154 }
155
156 fn typed_get() -> Box<dyn Any + Send + Sync> {
157 Box::new(GetValueTyped::<V> {
158 ty: Default::default(),
159 })
160 }
161
162 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool {
163 typed_get_value.0.is::<GetValueTyped<V>>()
164 }
165 }
166
167 impl ValueMeta {
168 pub fn new<I: IntoValueMeta + 'static>() -> Self {
169 Self {
170 name: I::name(),
171 deserialize: I::deserialize,
172 serialize: I::serialize,
173 typed_get: I::typed_get,
174 is_get_value_typed: I::is_get_value_typed,
175 }
176 }
177 }
178
179 pub struct OperationMeta {
180 pub name: String,
181 pub object_kind: String,
182 pub deserialize: fn(&[u8]) -> Result<AnyOperation, serde_json::Error>,
183 pub any_is_same: fn(&dyn Any) -> bool,
184 pub serialize_success: fn(AnySuccess) -> Result<Vec<u8>, serde_json::Error>,
185 pub serialize_error: fn(AnyFailure) -> Result<Vec<u8>, serde_json::Error>,
186 }
187
188 pub trait IntoOperationMeta<O> {
189 fn name() -> String;
190 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error>;
191 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error>;
192 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error>;
193 fn any_is_same(other: &dyn Any) -> bool;
194 }
195
196 impl<O, D> IntoOperationMeta<O> for D
197 where
198 D::Failure: 'static,
199 D::Success: 'static,
200 O: GiteratedObject,
201 D: GiteratedOperation<O> + 'static,
202 {
203 fn name() -> String {
204 D::operation_name().to_string()
205 }
206
207 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error> {
208 Ok(AnyOperation(
209 Arc::new(serde_json::from_slice::<D>(buffer)?) as Arc<dyn Any + Send + Sync>
210 ))
211 }
212
213 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> {
214 let to_serialize = success.0.downcast_ref::<D::Success>().unwrap();
215 serde_json::to_vec(&to_serialize)
216 }
217
218 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error> {
219 let to_serialize = failure.0.downcast_ref::<D::Failure>().unwrap();
220 serde_json::to_vec(&to_serialize)
221 }
222
223 fn any_is_same(other: &dyn Any) -> bool {
224 other.is::<D>()
225 }
226 }
227
228 impl OperationMeta {
229 pub fn new<O: GiteratedObject + 'static, I: IntoOperationMeta<O> + 'static>() -> Self {
230 Self {
231 name: I::name(),
232 deserialize: I::deserialize,
233 serialize_success: I::serialize_success,
234 serialize_error: I::serialize_failure,
235 object_kind: O::object_name().to_string(),
236 any_is_same: I::any_is_same,
237 }
238 }
239 }
240
241 pub struct ObjectMeta {
242 pub name: String,
243 pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>,
244 pub any_is_same: fn(&dyn Any) -> bool,
245 }
246
247 pub trait IntoObjectMeta: FromStr {
248 fn name() -> String;
249 fn any_is_same(other: &dyn Any) -> bool;
250 }
251
252 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
253 fn name() -> String {
254 O::object_name().to_string()
255 }
256
257 fn any_is_same(other: &dyn Any) -> bool {
258 other.is::<O>()
259 }
260 }
261
262 impl ObjectMeta {
263 pub fn new<I: IntoObjectMeta + Send + Sync + 'static>() -> Self {
264 Self {
265 name: I::name(),
266 from_str: Box::new(|source| {
267 let object = I::from_str(source).map_err(|_| ())?;
268
269 Ok(AnyObject(Arc::new(object) as Arc<dyn Any + Send + Sync>))
270 }),
271 any_is_same: I::any_is_same,
272 }
273 }
274 }
275
276 pub struct SettingMeta {
277 pub name: String,
278 pub deserialize: fn(Value) -> Result<AnySetting, serde_json::Error>,
279 pub serialize: fn(AnySetting) -> Result<Value, serde_json::Error>,
280 pub setting_updated: for<'fut> fn(
281 AnyObject,
282 AnySetting,
283 Arc<GiteratedStack>,
284 &StackOperationState,
285 ) -> LocalBoxFuture<'_, ()>,
286 }
287
288 pub trait IntoSettingMeta<O> {
289 fn name() -> String;
290 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error>;
291 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error>;
292 fn setting_updated(
293 object: AnyObject,
294 setting: AnySetting,
295 stack: Arc<GiteratedStack>,
296 operation_state: &StackOperationState,
297 ) -> LocalBoxFuture<'_, ()>;
298 }
299
300 impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta<O> for S {
301 fn name() -> String {
302 S::name().to_string()
303 }
304
305 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
306 Ok(AnySetting(Arc::new(serde_json::from_value::<S>(value)?)))
307 }
308
309 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
310 serde_json::to_value(setting.0.downcast_ref::<S>().unwrap())
311 }
312
313 fn setting_updated(
314 object: AnyObject,
315 setting: AnySetting,
316 stack: Arc<GiteratedStack>,
317 operation_state: &StackOperationState,
318 ) -> LocalBoxFuture<'_, ()> {
319 async move {
320 stack
321 .setting_update(
322 object.0.downcast_ref::<O>().unwrap().clone(),
323 setting.0.downcast_ref::<S>().unwrap().clone(),
324 operation_state,
325 )
326 .await
327 }
328 .boxed_local()
329 }
330 }
331
332 impl SettingMeta {
333 pub fn new<O: GiteratedObject, I: IntoSettingMeta<O> + 'static>() -> Self {
334 Self {
335 name: I::name(),
336 deserialize: I::deserialize,
337 serialize: I::serialize,
338 setting_updated: I::setting_updated,
339 }
340 }
341 }
342