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
parent: tbd commit: f94279e
Showing 3 changed files with 221 insertions and 118 deletions
giterated-stack/src/handler.rs
@@ -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
@@ -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
@@ -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 | } |