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

ambee/giterated

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

Fix internal call values

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨8e8ab90

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