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

ambee/giterated

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

Register GetSetting as an operation

Emilia - ⁨1⁩ year ago

parent: tbd commit: ⁨6a85805

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