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

ambee/giterated

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

`giterated_cache` initial implementation

# Giterated Stack - Added the ability for dynamic substack handlers to exist for operations relevant to caching. - Added type metadata to the dynamic types. # Giterated Cache - Created - Implemented caching and fetching from cache. Hell fucking yes!!!! It works so good. Are you snooping in the commit logs because you're curious about the history of giterated? Cool that it got so big... tell me I say hi :)

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨86afeef

⁨giterated-stack/src/meta/mod.rs⁩ - ⁨10528⁩ 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::new(serde_json::from_slice::<V>(buffer)?))
145 }
146
147 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> {
148 let value = value.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.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::new(serde_json::from_slice::<D>(buffer)?))
206 }
207
208 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> {
209 let to_serialize = success.0.downcast_ref::<D::Success>().unwrap();
210 serde_json::to_vec(&to_serialize)
211 }
212
213 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error> {
214 let to_serialize = failure.0.downcast_ref::<D::Failure>().unwrap();
215 serde_json::to_vec(&to_serialize)
216 }
217
218 fn any_is_same(other: &dyn Any) -> bool {
219 other.is::<D>()
220 }
221 }
222
223 impl OperationMeta {
224 pub fn new<O: GiteratedObject + 'static, I: IntoOperationMeta<O> + 'static>() -> Self {
225 Self {
226 name: I::name(),
227 deserialize: I::deserialize,
228 serialize_success: I::serialize_success,
229 serialize_error: I::serialize_failure,
230 object_kind: O::object_name().to_string(),
231 any_is_same: I::any_is_same,
232 }
233 }
234 }
235
236 pub struct ObjectMeta {
237 pub name: String,
238 pub to_str: Box<dyn Fn(AnyObject) -> String + Send + Sync>,
239 pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>,
240 pub any_is_same: fn(&dyn Any) -> bool,
241 }
242
243 pub trait IntoObjectMeta: FromStr {
244 fn name() -> String;
245 fn any_is_same(other: &dyn Any) -> bool;
246 }
247
248 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
249 fn name() -> String {
250 O::object_name().to_string()
251 }
252
253 fn any_is_same(other: &dyn Any) -> bool {
254 other.is::<O>()
255 }
256 }
257
258 impl ObjectMeta {
259 pub fn new<I: IntoObjectMeta + Send + Sync + 'static + GiteratedObject>() -> Self {
260 Self {
261 name: I::name(),
262 from_str: Box::new(|source| {
263 let object = I::from_str(source).map_err(|_| ())?;
264
265 Ok(AnyObject::new(object))
266 }),
267 to_str: Box::new(|source| {
268 let object: &I = source.downcast_ref().unwrap();
269
270 object.to_string()
271 }),
272 any_is_same: I::any_is_same,
273 }
274 }
275 }
276
277 pub struct SettingMeta {
278 pub name: String,
279 pub deserialize: fn(Value) -> Result<AnySetting, serde_json::Error>,
280 pub serialize: fn(AnySetting) -> Result<Value, serde_json::Error>,
281 pub setting_updated: for<'fut> fn(
282 AnyObject,
283 AnySetting,
284 Arc<GiteratedStack>,
285 &StackOperationState,
286 ) -> LocalBoxFuture<'_, ()>,
287 }
288
289 pub trait IntoSettingMeta<O> {
290 fn name() -> String;
291 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error>;
292 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error>;
293 fn setting_updated(
294 object: AnyObject,
295 setting: AnySetting,
296 stack: Arc<GiteratedStack>,
297 operation_state: &StackOperationState,
298 ) -> LocalBoxFuture<'_, ()>;
299 }
300
301 impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta<O> for S {
302 fn name() -> String {
303 S::name().to_string()
304 }
305
306 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
307 Ok(AnySetting::new::<O, S>(serde_json::from_value::<S>(value)?))
308 }
309
310 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
311 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
312 }
313
314 fn setting_updated(
315 object: AnyObject,
316 setting: AnySetting,
317 stack: Arc<GiteratedStack>,
318 operation_state: &StackOperationState,
319 ) -> LocalBoxFuture<'_, ()> {
320 async move {
321 stack
322 .setting_update(
323 object.downcast_ref::<O>().unwrap().clone(),
324 setting.downcast_ref::<S>().unwrap().clone(),
325 operation_state,
326 )
327 .await
328 }
329 .boxed_local()
330 }
331 }
332
333 impl SettingMeta {
334 pub fn new<O: GiteratedObject, I: IntoSettingMeta<O> + 'static>() -> Self {
335 Self {
336 name: I::name(),
337 deserialize: I::deserialize,
338 serialize: I::serialize,
339 setting_updated: I::setting_updated,
340 }
341 }
342 }
343