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

ambee/giterated

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

Giterated Stack `ObjectValue` and `Setting` refactor.

This refactor adds value and setting update events, as well as value getters. Additionally, the stack is now the owner of the ability to write settings into storage. This is accomplished with the `MetadataProvider` trait. This sets up the ground work for push federation, cache, and basically everything else. commit 7befc583cb3e0c6719506c550ed66ac76293413c Author: Amber <[email protected]> Date: Fri Sep 29 15:46:48 2023 -0500 Finish value and settings refactor in the stack. commit 3ac09994a0caafd1a0b95d9a781c7f202f20e75b Author: Amber <[email protected]> Date: Fri Sep 29 09:46:32 2023 -0500 Add set_setting handling back in commit 84fd31e3eae85d98fa68a28b333dbb32cde3bdb8 Author: Amber <[email protected]> Date: Wed Sep 27 06:36:31 2023 -0500 Remove some allocations from meta types commit 16c310ce3680c4a14ed35083b6a230aaecd43152 Author: Amber <[email protected]> Date: Wed Sep 27 05:35:03 2023 -0500 Add cargo metadata commit eb2520a20001bac7b21c6c3d34f62db32f0ada80 Author: Amber <[email protected]> Date: Wed Sep 27 05:26:27 2023 -0500 Refactor setting and value management to use the unified stack. Allows for tight management, inspection, and eventing of setting and value management. commit 901fe103da0fce4b40f33b0a8b64404049ae03cf Author: Amber <[email protected]> Date: Wed Sep 27 02:38:33 2023 -0500 Set up ground work for value / settings refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c377e4d

⁨giterated-stack/src/meta/mod.rs⁩ - ⁨7312⁩ bytes
Raw
1 use std::{any::Any, 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
12 use crate::{GiteratedStack, StackOperationState};
13
14 pub struct ValueMeta {
15 pub name: String,
16 pub deserialize: fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error>,
17 pub serialize: fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error>,
18 pub typed_get: fn() -> Box<dyn Any + Send + Sync>,
19 pub is_get_value_typed: fn(&Box<dyn Any + Send + Sync>) -> bool,
20 }
21
22 pub trait IntoValueMeta {
23 fn name() -> String;
24 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error>;
25 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error>;
26 fn typed_get() -> Box<dyn Any + Send + Sync>;
27 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool;
28 }
29
30 impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValueMeta for V {
31 fn name() -> String {
32 V::value_name().to_string()
33 }
34
35 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error> {
36 Ok(Box::new(serde_json::from_slice(buffer)?))
37 }
38
39 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> {
40 let value = value.downcast::<V>().unwrap();
41
42 serde_json::to_vec(&*value)
43 }
44
45 fn typed_get() -> Box<dyn Any + Send + Sync> {
46 Box::new(GetValueTyped::<V> {
47 value_name: V::value_name().to_string(),
48 ty: Default::default(),
49 })
50 }
51
52 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool {
53 typed_get_value.is::<GetValueTyped<V>>()
54 }
55 }
56
57 impl ValueMeta {
58 pub fn new<I: IntoValueMeta + 'static>() -> Self {
59 Self {
60 name: I::name(),
61 deserialize: I::deserialize,
62 serialize: I::serialize,
63 typed_get: I::typed_get,
64 is_get_value_typed: I::is_get_value_typed,
65 }
66 }
67 }
68
69 pub struct OperationMeta {
70 pub name: String,
71 pub object_kind: String,
72 pub deserialize: fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>,
73 pub any_is_same: fn(&dyn Any) -> bool,
74 pub serialize_success: fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>,
75 pub serialize_error: fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>,
76 }
77
78 pub trait IntoOperationMeta<O> {
79 fn name() -> String;
80 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>;
81 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
82 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
83 fn any_is_same(other: &dyn Any) -> bool;
84 }
85
86 impl<O, D> IntoOperationMeta<O> for D
87 where
88 D::Failure: 'static,
89 D::Success: 'static,
90 O: GiteratedObject,
91 D: GiteratedOperation<O> + 'static,
92 {
93 fn name() -> String {
94 D::operation_name().to_string()
95 }
96
97 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> {
98 Ok(Box::new(serde_json::from_slice::<D>(buffer)?) as Box<dyn Any + Send + Sync>)
99 }
100
101 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
102 let to_serialize = success.downcast::<D::Success>().unwrap();
103 serde_json::to_vec(&to_serialize)
104 }
105
106 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
107 let to_serialize = failure.downcast::<D::Failure>().unwrap();
108 serde_json::to_vec(&to_serialize)
109 }
110
111 fn any_is_same(other: &dyn Any) -> bool {
112 other.is::<D>()
113 }
114 }
115
116 impl OperationMeta {
117 pub fn new<O: GiteratedObject + 'static, I: IntoOperationMeta<O> + 'static>() -> Self {
118 Self {
119 name: I::name(),
120 deserialize: I::deserialize,
121 serialize_success: I::serialize_success,
122 serialize_error: I::serialize_failure,
123 object_kind: O::object_name().to_string(),
124 any_is_same: I::any_is_same,
125 }
126 }
127 }
128
129 pub struct ObjectMeta {
130 pub name: String,
131 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
132 pub any_is_same: fn(&dyn Any) -> bool,
133 }
134
135 pub trait IntoObjectMeta: FromStr {
136 fn name() -> String;
137 fn any_is_same(other: &dyn Any) -> bool;
138 }
139
140 impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
141 fn name() -> String {
142 O::object_name().to_string()
143 }
144
145 fn any_is_same(other: &dyn Any) -> bool {
146 other.is::<O>()
147 }
148 }
149
150 impl ObjectMeta {
151 pub fn new<I: IntoObjectMeta + Send + Sync + 'static>() -> Self {
152 Self {
153 name: I::name(),
154 from_str: Box::new(|source| {
155 let object = I::from_str(source).map_err(|_| ())?;
156
157 Ok(Box::new(object) as Box<dyn Any + Send + Sync>)
158 }),
159 any_is_same: I::any_is_same,
160 }
161 }
162 }
163
164 pub struct SettingMeta {
165 pub name: String,
166 pub deserialize: fn(Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>,
167 pub serialize: fn(&(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error>,
168 pub setting_updated: for<'fut> fn(
169 Box<dyn Any + Send + Sync>,
170 Box<dyn Any + Send + Sync>,
171 Arc<GiteratedStack>,
172 &StackOperationState,
173 ) -> LocalBoxFuture<'_, ()>,
174 }
175
176 pub trait IntoSettingMeta<O> {
177 fn name() -> String;
178 fn deserialize(value: Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>;
179 fn serialize(setting: &(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error>;
180 fn setting_updated(
181 object: Box<dyn Any + Send + Sync>,
182 setting: Box<dyn Any + Send + Sync>,
183 stack: Arc<GiteratedStack>,
184 operation_state: &StackOperationState,
185 ) -> LocalBoxFuture<'_, ()>;
186 }
187
188 impl<O: GiteratedObject + 'static, S: Setting + 'static> IntoSettingMeta<O> for S {
189 fn name() -> String {
190 S::name().to_string()
191 }
192
193 fn deserialize(value: Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> {
194 Ok(Box::new(serde_json::from_value::<S>(value)?))
195 }
196
197 fn serialize(setting: &(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error> {
198 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
199 }
200
201 fn setting_updated(
202 object: Box<dyn Any + Send + Sync>,
203 setting: Box<dyn Any + Send + Sync>,
204 stack: Arc<GiteratedStack>,
205 operation_state: &StackOperationState,
206 ) -> LocalBoxFuture<'_, ()> {
207 async move {
208 stack
209 .setting_update(
210 *object.downcast::<O>().unwrap(),
211 *setting.downcast::<S>().unwrap(),
212 operation_state,
213 )
214 .await
215 }
216 .boxed_local()
217 }
218 }
219
220 impl SettingMeta {
221 pub fn new<O: GiteratedObject, I: IntoSettingMeta<O> + 'static>() -> Self {
222 Self {
223 name: I::name(),
224 deserialize: I::deserialize,
225 serialize: I::serialize,
226 setting_updated: I::setting_updated,
227 }
228 }
229 }
230