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

ambee/giterated

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

Create `NetworkedSubstack`.

# giterated-protocol - Create `NetworkedSubstack` which will handle all networked operations giterated needs - Add support for `NetworkedSubstack` for both the daemon and client - Pipe everything through but leave APIs temp # `giterated-daemon` - Remove a bunch of random old code, dead code, and files that aren't needed. - Moved all connection handling to `client.rs`, simplified connection logic with new types

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨202bb12

⁨giterated-stack/src/meta/mod.rs⁩ - ⁨10723⁩ 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 home_uri: fn(AnyObject) -> String,
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 fn home_uri(object: AnyObject) -> String;
248 }
249
250 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
251 fn name() -> String {
252 O::object_name().to_string()
253 }
254
255 fn any_is_same(other: &dyn Any) -> bool {
256 other.is::<O>()
257 }
258
259 fn home_uri(_object: AnyObject) -> String {
260 todo!()
261 }
262 }
263
264 impl ObjectMeta {
265 pub fn new<I: IntoObjectMeta + Send + Sync + 'static + GiteratedObject>() -> Self {
266 Self {
267 name: I::name(),
268 from_str: Box::new(|source| {
269 let object = I::from_str(source).map_err(|_| ())?;
270
271 Ok(AnyObject::new(object))
272 }),
273 to_str: Box::new(|source| {
274 let object: &I = source.downcast_ref().unwrap();
275
276 object.to_string()
277 }),
278 any_is_same: I::any_is_same,
279 home_uri: I::home_uri,
280 }
281 }
282 }
283
284 pub struct SettingMeta {
285 pub name: String,
286 pub deserialize: fn(Value) -> Result<AnySetting, serde_json::Error>,
287 pub serialize: fn(AnySetting) -> Result<Value, serde_json::Error>,
288 pub setting_updated: for<'fut> fn(
289 AnyObject,
290 AnySetting,
291 Arc<GiteratedStack>,
292 &StackOperationState,
293 ) -> LocalBoxFuture<'_, ()>,
294 }
295
296 pub trait IntoSettingMeta<O> {
297 fn name() -> String;
298 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error>;
299 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error>;
300 fn setting_updated(
301 object: AnyObject,
302 setting: AnySetting,
303 stack: Arc<GiteratedStack>,
304 operation_state: &StackOperationState,
305 ) -> LocalBoxFuture<'_, ()>;
306 }
307
308 impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta<O> for S {
309 fn name() -> String {
310 S::name().to_string()
311 }
312
313 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
314 Ok(AnySetting::new::<O, S>(serde_json::from_value::<S>(value)?))
315 }
316
317 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
318 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
319 }
320
321 fn setting_updated(
322 object: AnyObject,
323 setting: AnySetting,
324 stack: Arc<GiteratedStack>,
325 operation_state: &StackOperationState,
326 ) -> LocalBoxFuture<'_, ()> {
327 async move {
328 stack
329 .setting_update(
330 object.downcast_ref::<O>().unwrap().clone(),
331 setting.downcast_ref::<S>().unwrap().clone(),
332 operation_state,
333 )
334 .await
335 }
336 .boxed_local()
337 }
338 }
339
340 impl SettingMeta {
341 pub fn new<O: GiteratedObject, I: IntoSettingMeta<O> + 'static>() -> Self {
342 Self {
343 name: I::name(),
344 deserialize: I::deserialize,
345 serialize: I::serialize,
346 setting_updated: I::setting_updated,
347 }
348 }
349 }
350