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/meta/mod.rs⁩ - ⁨12458⁩ 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::{SetSetting, Setting},
8 value::{GetValue, 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 if self
78 .values
79 .insert(ObjectValuePair::from_types::<O, V>(), ValueMeta::new::<V>())
80 .is_some()
81 {
82 trace!(
83 "Registration of value <{}>::{} overwrote previous registration.",
84 O::object_name(),
85 V::value_name()
86 );
87 } else {
88 trace!(
89 "Registration of value <{}>::{}.",
90 O::object_name(),
91 V::value_name()
92 );
93 }
94
95 self.operations.insert(
96 ObjectOperationPair::from_types::<O, GetValue>(),
97 OperationMeta::new::<O, GetValue>(),
98 );
99 }
100
101 pub fn register_setting<O: GiteratedObject + 'static, S: Setting + 'static + Clone>(&mut self) {
102 if self
103 .settings
104 .insert(
105 ObjectSettingPair::from_types::<O, S>(),
106 SettingMeta::new::<O, S>(),
107 )
108 .is_some()
109 {
110 trace!(
111 "Registration of setting {} overwrote previous registration.",
112 S::name()
113 );
114 } else {
115 trace!("Registration of setting {}.", S::name());
116 }
117
118 self.operations.insert(
119 ObjectOperationPair::from_types::<O, SetSetting>(),
120 OperationMeta::new::<O, SetSetting>(),
121 );
122 }
123
124 pub fn append(&mut self, other: Self) {
125 self.objects.extend(other.objects);
126 self.operations.extend(other.operations);
127 self.values.extend(other.values);
128 self.settings.extend(other.settings);
129 }
130 }
131
132 pub struct ValueMeta {
133 pub name: String,
134 pub deserialize: fn(&[u8]) -> Result<AnyValue, serde_json::Error>,
135 pub serialize: fn(AnyValue) -> Result<Vec<u8>, serde_json::Error>,
136 pub typed_get: fn() -> Box<dyn Any + Send + Sync>,
137 pub is_get_value_typed: fn(AnyOperation) -> bool,
138 }
139
140 pub trait IntoValueMeta {
141 fn name() -> String;
142 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error>;
143 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error>;
144 fn typed_get() -> Box<dyn Any + Send + Sync>;
145 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool;
146 }
147
148 impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValueMeta for V {
149 fn name() -> String {
150 V::value_name().to_string()
151 }
152
153 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error> {
154 Ok(AnyValue::new(serde_json::from_slice::<V>(buffer)?))
155 }
156
157 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> {
158 let value = value.downcast_ref::<V>().unwrap();
159
160 serde_json::to_vec(&*value)
161 }
162
163 fn typed_get() -> Box<dyn Any + Send + Sync> {
164 Box::new(GetValueTyped::<V> {
165 ty: Default::default(),
166 })
167 }
168
169 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool {
170 typed_get_value.is::<GetValueTyped<V>>()
171 }
172 }
173
174 impl ValueMeta {
175 pub fn new<I: IntoValueMeta + 'static>() -> Self {
176 Self {
177 name: I::name(),
178 deserialize: I::deserialize,
179 serialize: I::serialize,
180 typed_get: I::typed_get,
181 is_get_value_typed: I::is_get_value_typed,
182 }
183 }
184 }
185
186 pub struct OperationMeta {
187 pub name: String,
188 pub object_kind: String,
189 pub serialize: fn(AnyOperation) -> Result<Vec<u8>, serde_json::Error>,
190 pub deserialize: fn(&[u8]) -> Result<AnyOperation, serde_json::Error>,
191 pub any_is_same: fn(&dyn Any) -> bool,
192 pub serialize_success: fn(AnySuccess) -> Result<Vec<u8>, serde_json::Error>,
193 pub serialize_error: fn(AnyFailure) -> Result<Vec<u8>, serde_json::Error>,
194 pub deserialize_success: fn(Vec<u8>) -> Result<AnySuccess, serde_json::Error>,
195 pub deserialize_failure: fn(Vec<u8>) -> Result<AnyFailure, serde_json::Error>,
196 }
197
198 pub trait IntoOperationMeta<O> {
199 fn name() -> String;
200 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error>;
201 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error>;
202 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error>;
203 fn deserialize_success(success: Vec<u8>) -> Result<AnySuccess, serde_json::Error>;
204 fn deserialize_failure(failure: Vec<u8>) -> Result<AnyFailure, serde_json::Error>;
205 fn any_is_same(other: &dyn Any) -> bool;
206 fn serialize(operation: AnyOperation) -> Result<Vec<u8>, serde_json::Error>;
207 }
208
209 impl<O, D> IntoOperationMeta<O> for D
210 where
211 D::Failure: 'static,
212 D::Success: 'static,
213 O: GiteratedObject + 'static,
214 D: GiteratedOperation<O> + 'static,
215 {
216 fn name() -> String {
217 D::operation_name().to_string()
218 }
219
220 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error> {
221 Ok(AnyOperation::new(serde_json::from_slice::<D>(buffer)?))
222 }
223
224 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> {
225 let to_serialize = success.0.downcast_ref::<D::Success>().unwrap();
226 serde_json::to_vec(&to_serialize)
227 }
228
229 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error> {
230 let to_serialize = failure.0.downcast_ref::<D::Failure>().unwrap();
231 serde_json::to_vec(&to_serialize)
232 }
233
234 fn any_is_same(other: &dyn Any) -> bool {
235 other.is::<D>()
236 }
237
238 fn serialize(operation: AnyOperation) -> Result<Vec<u8>, serde_json::Error> {
239 let operation: &D = operation.downcast_ref().unwrap();
240
241 serde_json::to_vec(operation)
242 }
243
244 fn deserialize_success(success: Vec<u8>) -> Result<AnySuccess, serde_json::Error> {
245 let success: D::Success = serde_json::from_slice(&success)?;
246
247 Ok(AnySuccess(Arc::new(success)))
248 }
249
250 fn deserialize_failure(failure: Vec<u8>) -> Result<AnyFailure, serde_json::Error> {
251 let failure: D::Failure = serde_json::from_slice(&failure)?;
252
253 Ok(AnyFailure(Arc::new(failure)))
254 }
255 }
256
257 impl OperationMeta {
258 pub fn new<O: GiteratedObject + 'static, I: IntoOperationMeta<O> + 'static>() -> Self {
259 Self {
260 name: I::name(),
261 deserialize: I::deserialize,
262 serialize_success: I::serialize_success,
263 serialize_error: I::serialize_failure,
264 object_kind: O::object_name().to_string(),
265 any_is_same: I::any_is_same,
266 serialize: I::serialize,
267 deserialize_success: I::deserialize_success,
268 deserialize_failure: I::deserialize_failure,
269 }
270 }
271 }
272
273 pub struct ObjectMeta {
274 pub name: String,
275 pub to_str: Box<dyn Fn(AnyObject) -> String + Send + Sync>,
276 pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>,
277 pub home_uri: fn(AnyObject) -> String,
278 pub any_is_same: fn(&dyn Any) -> bool,
279 }
280
281 pub trait IntoObjectMeta: FromStr {
282 fn name() -> String;
283 fn any_is_same(other: &dyn Any) -> bool;
284 fn home_uri(object: AnyObject) -> String;
285 }
286
287 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
288 fn name() -> String {
289 O::object_name().to_string()
290 }
291
292 fn any_is_same(other: &dyn Any) -> bool {
293 other.is::<O>()
294 }
295
296 fn home_uri(object: AnyObject) -> String {
297 let object: &O = object.downcast_ref().unwrap();
298
299 object.home_uri()
300 }
301 }
302
303 impl ObjectMeta {
304 pub fn new<I: IntoObjectMeta + Send + Sync + 'static + GiteratedObject>() -> Self {
305 Self {
306 name: I::name(),
307 from_str: Box::new(|source| {
308 let object = I::from_str(source).map_err(|_| ())?;
309
310 Ok(AnyObject::new(object))
311 }),
312 to_str: Box::new(|source| {
313 let object: &I = source.downcast_ref().unwrap();
314
315 object.to_string()
316 }),
317 any_is_same: I::any_is_same,
318 home_uri: <I as IntoObjectMeta>::home_uri,
319 }
320 }
321 }
322
323 pub struct SettingMeta {
324 pub name: String,
325 pub deserialize: fn(Value) -> Result<AnySetting, serde_json::Error>,
326 pub serialize: fn(AnySetting) -> Result<Value, serde_json::Error>,
327 pub setting_updated: for<'fut> fn(
328 AnyObject,
329 AnySetting,
330 GiteratedStack<StackOperationState>,
331 &StackOperationState,
332 ) -> LocalBoxFuture<'_, ()>,
333 }
334
335 pub trait IntoSettingMeta<O> {
336 fn name() -> String;
337 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error>;
338 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error>;
339 fn setting_updated(
340 object: AnyObject,
341 setting: AnySetting,
342 stack: GiteratedStack<StackOperationState>,
343 operation_state: &StackOperationState,
344 ) -> LocalBoxFuture<'_, ()>;
345 }
346
347 impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta<O> for S {
348 fn name() -> String {
349 S::name().to_string()
350 }
351
352 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
353 Ok(AnySetting::new::<O, S>(serde_json::from_value::<S>(value)?))
354 }
355
356 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
357 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
358 }
359
360 fn setting_updated(
361 object: AnyObject,
362 setting: AnySetting,
363 stack: GiteratedStack<StackOperationState>,
364 operation_state: &StackOperationState,
365 ) -> LocalBoxFuture<'_, ()> {
366 async move {
367 stack
368 .setting_update(
369 object.downcast_ref::<O>().unwrap().clone(),
370 setting.downcast_ref::<S>().unwrap().clone(),
371 operation_state,
372 )
373 .await
374 }
375 .boxed_local()
376 }
377 }
378
379 impl SettingMeta {
380 pub fn new<O: GiteratedObject, I: IntoSettingMeta<O> + 'static>() -> Self {
381 Self {
382 name: I::name(),
383 deserialize: I::deserialize,
384 serialize: I::serialize,
385 setting_updated: I::setting_updated,
386 }
387 }
388 }
389