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

ambee/giterated

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

Merge branch dyn_inherent into master

This is a squashed commit of the following: commit 6b7c04bc1aae470d9c95b9c5f4e5698bd8c8fef0 Author: Amber <[email protected]> Date: Tue Sep 26 14:03:52 2023 -0500 Give meta types better ergonomics and location

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨f94279e

Showing ⁨⁨3⁩ changed files⁩ with ⁨⁨221⁩ insertions⁩ and ⁨⁨118⁩ deletions⁩

giterated-stack/src/handler.rs

View file
@@ -14,8 +14,8 @@ use giterated_models::{
14 14 settings::{GetSetting, GetSettingError, SetSetting, Setting},
15 15 value::{AnyValue, GetValue, GetValueTyped, GiteratedObjectValue},
16 16 };
17 use serde_json::Value;
18 use tracing::{info, trace};
17
18 use tracing::trace;
19 19
20 20 use crate::{
21 21 GiteratedOperationHandler, ObjectMeta, ObjectOperationPair, ObjectValuePair, OperationMeta,
@@ -315,11 +315,7 @@ impl RuntimeMetadata {
315 315 fn register_object<O: GiteratedObject + 'static>(&mut self) {
316 316 let object_name = O::object_name().to_string();
317 317
318 let object_meta = ObjectMeta {
319 name: object_name.clone(),
320 from_str: Box::new(|str| Ok(Box::new(O::from_str(&str).map_err(|_| ())?))),
321 any_is_same: Box::new(|any| any.is::<O>()),
322 };
318 let object_meta = ObjectMeta::new::<O>();
323 319
324 320 if self.objects.insert(object_name, object_meta).is_some() {
325 321 trace!(
@@ -344,23 +340,7 @@ impl RuntimeMetadata {
344 340 object_name: object_name.clone(),
345 341 operation_name: operation_name.clone(),
346 342 },
347 OperationMeta {
348 name: operation_name,
349 object_kind: object_name,
350 deserialize: Box::new(|bytes| {
351 Ok(Box::new(serde_json::from_slice::<D>(bytes)?)
352 as Box<dyn Any + Send + Sync>)
353 }),
354 any_is_same: Box::new(|any_box| any_box.is::<D>()),
355 serialize_success: Box::new(|any| {
356 let to_serialize = any.downcast::<D::Success>().unwrap();
357 serde_json::to_vec(&to_serialize)
358 }),
359 serialize_error: Box::new(|any| {
360 let to_serialize = any.downcast::<D::Failure>().unwrap();
361 serde_json::to_vec(&to_serialize)
362 }),
363 },
343 OperationMeta::new::<O, D>(),
364 344 )
365 345 .is_some()
366 346 {
@@ -386,7 +366,6 @@ impl RuntimeMetadata {
386 366 ) {
387 367 let object_name = O::object_name().to_string();
388 368 let value_name = V::value_name().to_string();
389 let value_name_for_get = V::value_name().to_string();
390 369
391 370 if self
392 371 .values
@@ -395,22 +374,7 @@ impl RuntimeMetadata {
395 374 object_kind: object_name.clone(),
396 375 value_kind: value_name.clone(),
397 376 },
398 ValueMeta {
399 name: value_name.clone(),
400 deserialize: Box::new(|bytes| Ok(Box::new(serde_json::from_slice(&bytes)?))),
401 serialize: Box::new(|value| {
402 let value = value.downcast::<V>().unwrap();
403
404 Ok(serde_json::to_vec(&*value)?)
405 }),
406 typed_get: Box::new(move || {
407 Box::new(GetValueTyped::<V> {
408 value_name: value_name_for_get.clone(),
409 ty: Default::default(),
410 })
411 }),
412 is_get_value_typed: Box::new(move |typed| typed.is::<GetValueTyped<V>>()),
413 },
377 ValueMeta::new::<V>(),
414 378 )
415 379 .is_some()
416 380 {
@@ -433,14 +397,7 @@ impl RuntimeMetadata {
433 397
434 398 if self
435 399 .settings
436 .insert(
437 setting_name.clone(),
438 SettingMeta {
439 name: setting_name,
440 deserialize: Box::new(|bytes| Ok(Box::new(serde_json::from_slice(bytes)?))),
441 serialize: Box::new(|source| Ok(*source.downcast::<Value>().unwrap())),
442 },
443 )
400 .insert(setting_name.clone(), SettingMeta::new::<S>())
444 401 .is_some()
445 402 {
446 403 trace!(
@@ -499,20 +456,16 @@ impl GiteratedStack {
499 456 .await;
500 457 } else if message.operation == "get_setting" {
501 458 let operation: GetSetting = serde_json::from_slice(&message.payload.0).unwrap();
502 info!("1");
503 459 let setting_meta = self
504 460 .metadata
505 461 .settings
506 462 .get(&operation.setting_name)
507 463 .ok_or_else(|| OperationError::Unhandled)?;
508 info!("2");
509 464 let raw_result = self
510 465 .get_setting(object, object_type.clone(), operation, operation_state)
511 466 .await;
512 info!("3");
513 467 return match raw_result {
514 468 Ok(success) => {
515 info!("3a");
516 469 // Success is the setting type, serialize it
517 470 let serialized = (setting_meta.serialize)(success).unwrap();
518 471
@@ -520,7 +473,6 @@ impl GiteratedStack {
520 473 }
521 474 Err(err) => Err(match err {
522 475 OperationError::Operation(failure) => {
523 info!("3b");
524 476 // We know how to resolve this type
525 477 let failure: GetSettingError = *failure.downcast().unwrap();
526 478
@@ -703,23 +655,6 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
703 655 let object = Box::new(in_object.clone()) as Box<dyn Any + Send + Sync>;
704 656 let operation = Box::new(payload) as Box<dyn Any + Send + Sync>;
705 657
706 // We need to determine the type of the object, iterate through all known
707 // object types and check if the &dyn Any we have is the same type as the
708 // object type.
709 let object_type = {
710 let mut object_type = None;
711
712 for (object_name, object_meta) in self.metadata.objects.iter() {
713 if (object_meta.any_is_same)(&in_object) {
714 object_type = Some(object_name.clone());
715 break;
716 }
717 }
718
719 object_type
720 }
721 .ok_or_else(|| OperationError::Unhandled)?;
722
723 658 // We need to hijack get_value, set_setting, and get_setting.
724 659 if operation_name == "get_value" {
725 660 let mut value_meta = None;
@@ -734,10 +669,14 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
734 669
735 670 let value_name = value_meta.name.clone();
736 671
737 trace!("Handling get_value for {}::{}", object_type, value_name);
672 trace!(
673 "Handling get_value for {}::{}",
674 O::object_name(),
675 value_name
676 );
738 677
739 678 for (target, getter) in self.value_getters.iter() {
740 if target.object_kind != object_type {
679 if target.object_kind != O::object_name() {
741 680 continue;
742 681 }
743 682
@@ -763,16 +702,14 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
763 702 return Err(OperationError::Unhandled);
764 703 } else if operation.is::<GetSetting>() {
765 704 let get_setting: Box<GetSetting> = operation.downcast().unwrap();
766 let _setting_name = get_setting.setting_name.clone();
767
768 let _setting_meta = self
769 .metadata
770 .settings
771 .get(&object_type)
772 .ok_or_else(|| OperationError::Unhandled)?;
773 705
774 706 let raw_result = self
775 .get_setting(object, object_type.clone(), *get_setting, operation_state)
707 .get_setting(
708 object,
709 O::object_name().to_string(),
710 *get_setting,
711 operation_state,
712 )
776 713 .await;
777 714
778 715 return match raw_result {
@@ -804,7 +741,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
804 741
805 742 for (target, operation_meta) in self.metadata.operations.iter() {
806 743 // Skip elements that we know will not match
807 if target.object_name != object_type {
744 if target.object_name != O::object_name() {
808 745 continue;
809 746 }
810 747

giterated-stack/src/lib.rs

View file
@@ -1,7 +1,7 @@
1 1 mod handler;
2 mod meta;
2 3 pub use handler::{GiteratedStack, GiteratedStackState, *};
3 use serde_json::Value;
4
4 pub use meta::*;
5 5 pub mod state;
6 6 pub mod update;
7 7
@@ -30,40 +30,6 @@ struct ObjectOperationPair {
30 30 pub operation_name: String,
31 31 }
32 32
33 pub struct SettingMeta {
34 pub name: String,
35 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
36 pub serialize:
37 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Value, serde_json::Error> + Send + Sync>,
38 }
39
40 pub struct ValueMeta {
41 pub name: String,
42 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
43 pub serialize:
44 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
45 pub typed_get: Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
46 pub is_get_value_typed: Box<dyn Fn(&Box<dyn Any + Send + Sync>) -> bool + Send + Sync>,
47 }
48
49 pub struct ObjectMeta {
50 pub name: String,
51 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
52 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
53 }
54
55 pub struct OperationMeta {
56 pub name: String,
57 pub object_kind: String,
58 pub deserialize:
59 Box<dyn Fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> + Send + Sync>,
60 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
61 pub serialize_success:
62 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
63 pub serialize_error:
64 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
65 }
66
67 33 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
68 34 pub struct ObjectValuePair {
69 35 pub object_kind: String,

giterated-stack/src/meta/mod.rs

View file
@@ -0,0 +1,200 @@
1 use std::{any::Any, str::FromStr};
2
3 use giterated_models::{
4 object::GiteratedObject,
5 operation::GiteratedOperation,
6 settings::Setting,
7 value::{GetValueTyped, GiteratedObjectValue},
8 };
9 use serde_json::Value;
10
11 pub struct ValueMeta {
12 pub name: String,
13 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
14 pub serialize:
15 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
16 pub typed_get: Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
17 pub is_get_value_typed: Box<dyn Fn(&Box<dyn Any + Send + Sync>) -> bool + Send + Sync>,
18 }
19
20 pub trait IntoValueMeta {
21 fn name() -> String;
22 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error>;
23 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error>;
24 fn typed_get() -> Box<dyn Any + Send + Sync>;
25 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool;
26 }
27
28 impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValueMeta for V {
29 fn name() -> String {
30 V::value_name().to_string()
31 }
32
33 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error> {
34 Ok(Box::new(serde_json::from_slice(&buffer)?))
35 }
36
37 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> {
38 let value = value.downcast::<V>().unwrap();
39
40 Ok(serde_json::to_vec(&*value)?)
41 }
42
43 fn typed_get() -> Box<dyn Any + Send + Sync> {
44 Box::new(GetValueTyped::<V> {
45 value_name: V::value_name().to_string(),
46 ty: Default::default(),
47 })
48 }
49
50 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool {
51 typed_get_value.is::<GetValueTyped<V>>()
52 }
53 }
54
55 impl ValueMeta {
56 pub fn new<I: IntoValueMeta + 'static>() -> Self {
57 Self {
58 name: I::name(),
59 deserialize: Box::new(I::deserialize) as _,
60 serialize: Box::new(I::serialize) as _,
61 typed_get: Box::new(I::typed_get) as _,
62 is_get_value_typed: Box::new(I::is_get_value_typed) as _,
63 }
64 }
65 }
66
67 pub struct OperationMeta {
68 pub name: String,
69 pub object_kind: String,
70 pub deserialize:
71 Box<dyn Fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> + Send + Sync>,
72 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
73 pub serialize_success:
74 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
75 pub serialize_error:
76 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
77 }
78
79 pub trait IntoOperationMeta<O> {
80 fn name() -> String;
81 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>;
82 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
83 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
84 fn any_is_same(other: &dyn Any) -> bool;
85 }
86
87 impl<O, D> IntoOperationMeta<O> for D
88 where
89 D::Failure: 'static,
90 D::Success: 'static,
91 O: GiteratedObject,
92 D: GiteratedOperation<O> + 'static,
93 {
94 fn name() -> String {
95 D::operation_name().to_string()
96 }
97
98 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> {
99 Ok(Box::new(serde_json::from_slice::<D>(buffer)?) as Box<dyn Any + Send + Sync>)
100 }
101
102 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
103 let to_serialize = success.downcast::<D::Success>().unwrap();
104 serde_json::to_vec(&to_serialize)
105 }
106
107 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
108 let to_serialize = failure.downcast::<D::Failure>().unwrap();
109 serde_json::to_vec(&to_serialize)
110 }
111
112 fn any_is_same(other: &dyn Any) -> bool {
113 other.is::<D>()
114 }
115 }
116
117 impl OperationMeta {
118 pub fn new<O: GiteratedObject + 'static, I: IntoOperationMeta<O> + 'static>() -> Self {
119 Self {
120 name: I::name(),
121 deserialize: Box::new(I::deserialize) as _,
122 serialize_success: Box::new(I::serialize_success) as _,
123 serialize_error: Box::new(I::serialize_failure) as _,
124 object_kind: O::object_name().to_string(),
125 any_is_same: Box::new(I::any_is_same) as _,
126 }
127 }
128 }
129
130 pub struct ObjectMeta {
131 pub name: String,
132 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
133 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
134 }
135
136 pub trait IntoObjectMeta: FromStr {
137 fn name() -> String;
138 fn any_is_same(other: &dyn Any) -> bool;
139 }
140
141 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
142 fn name() -> String {
143 O::object_name().to_string()
144 }
145
146 fn any_is_same(other: &dyn Any) -> bool {
147 other.is::<O>()
148 }
149 }
150
151 impl ObjectMeta {
152 pub fn new<I: IntoObjectMeta + Send + Sync + 'static>() -> Self {
153 Self {
154 name: I::name(),
155 from_str: Box::new(|source| {
156 let object = I::from_str(source).map_err(|_| ())?;
157
158 Ok(Box::new(object) as Box<dyn Any + Send + Sync>)
159 }),
160 any_is_same: Box::new(I::any_is_same) as _,
161 }
162 }
163 }
164
165 pub struct SettingMeta {
166 pub name: String,
167 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
168 pub serialize:
169 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Value, serde_json::Error> + Send + Sync>,
170 }
171
172 pub trait IntoSettingMeta {
173 fn name() -> String;
174 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error>;
175 fn serialize(setting: Box<dyn Any + Send + Sync>) -> Result<Value, serde_json::Error>;
176 }
177
178 impl<S: Setting> IntoSettingMeta for S {
179 fn name() -> String {
180 S::name().to_string()
181 }
182
183 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error> {
184 Ok(Box::new(serde_json::from_slice(buffer)?))
185 }
186
187 fn serialize(setting: Box<dyn Any + Send + Sync>) -> Result<Value, serde_json::Error> {
188 Ok(*setting.downcast::<Value>().unwrap())
189 }
190 }
191
192 impl SettingMeta {
193 pub fn new<I: IntoSettingMeta + 'static>() -> Self {
194 Self {
195 name: I::name(),
196 deserialize: Box::new(I::deserialize) as _,
197 serialize: Box::new(I::serialize) as _,
198 }
199 }
200 }