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

Showing ⁨⁨12⁩ changed files⁩ with ⁨⁨617⁩ insertions⁩ and ⁨⁨499⁩ deletions⁩

Cargo.lock

View file
@@ -844,6 +844,7 @@ dependencies = [
844 844 "futures-util",
845 845 "git2",
846 846 "giterated-api",
847 "giterated-cache",
847 848 "giterated-models",
848 849 "giterated-stack",
849 850 "jsonwebtoken",

giterated-cache/src/cache_get.rs

View file
@@ -14,3 +14,41 @@
14 14 // ) -> Result<Value, OperationError<anyhow::Error>> {
15 15 // todo!()
16 16 // }
17
18 use std::sync::Arc;
19
20 use giterated_models::error::OperationError;
21 use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState};
22 use tracing::trace;
23
24 use crate::{CacheKey, CacheSubstack};
25
26 pub async fn get_cached(
27 object: AnyObject,
28 value_kind: String,
29 cache: CacheSubstack,
30 _operation_state: StackOperationState,
31 stack: Arc<GiteratedStack>,
32 ) -> Result<AnyValue, OperationError<anyhow::Error>> {
33 let object_meta = stack
34 .metadata
35 .objects
36 .get(object.kind())
37 .ok_or_else(|| OperationError::Unhandled)?;
38 let object_str = (object_meta.to_str)(object.clone());
39 let cache_key = CacheKey {
40 object: object_str,
41 value_name: value_kind.clone(),
42 };
43
44 trace!("Check cache for {}::{}", object.kind(), value_kind);
45
46 if let Some(cached_value) = cache.cache.get(&cache_key).await {
47 trace!("Found cached for {}::{}", object.kind(), value_kind);
48
49 Ok(cached_value.clone())
50 } else {
51 trace!("Nothing cached for {}::{}", object.kind(), value_kind);
52 Err(OperationError::Unhandled)
53 }
54 }

giterated-cache/src/cache_update.rs

View file
@@ -1,348 +1,42 @@
1 // use std::{any::Any, pin::Pin, process::Output, sync::Arc};
2
3 // use futures_util::{future::LocalBoxFuture, Future, FutureExt};
4 // use giterated_models::{
5 // error::{ExtractorError, OperationError, RepositoryError},
6 // object::GiteratedObject,
7 // operation::GiteratedOperation,
8 // repository::{Repository, RepositoryBranch, RepositoryBranchesRequest},
9 // settings::SetSetting,
10 // user::{DisplayName, User},
11 // value::{GetValue, GiteratedObjectValue},
12 // };
13 // use giterated_stack::{
14 // AuthorizedUser, FromOperationState, GiteratedStack, MissingValue, StackOperationState,
15 // };
16
17 // use crate::CacheSubstack;
18
19 // async fn value_update(
20 // object: AnyObject<'_>,
21 // value: AnyValue<'_>,
22 // cache: CacheSubstack,
23 // stack: Arc<GiteratedStack>,
24 // ) -> Result<(), anyhow::Error> {
25 // todo!()
26 // }
27
28 // pub struct AnyObject<'o>(&'o (dyn Any + Send + Sync));
29
30 // pub struct AnyValue<'v>(&'v (dyn Any + Send + Sync));
31
32 // #[async_trait::async_trait(?Send)]
33 // pub trait GiteratedHandler<RequiredParameters, AdditionalParameters, State, OperationState, Output>
34 // {
35 // async fn handle(
36 // &self,
37 // parameters: RequiredParameters,
38 // additional_parameters: AdditionalParameters,
39 // state: Arc<State>,
40 // operation_state: &OperationState,
41 // ) -> Output;
42 // }
43
44 // #[async_trait::async_trait(?Send)]
45 // impl<R1, S, O, Output, F, Fut> GiteratedHandler<(R1,), (), S, O, Output> for F
46 // where
47 // F: FnMut(R1, S, &O) -> Fut,
48 // Fut: Future<Output = Output>,
49 // S: 'static,
50 // R1: 'static,
51 // {
52 // async fn handle(
53 // &self,
54 // parameters: (R1,),
55 // additional_parameters: (),
56 // state: Arc<S>,
57 // operation_state: &O,
58 // ) -> Output {
59 // todo!()
60 // }
61 // }
62
63 // #[async_trait::async_trait(?Send)]
64 // impl<R1, A1, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1,), S, O, Output> for F
65 // where
66 // F: FnMut(R1, S, &O, A1) -> Fut,
67 // Fut: Future<Output = Output>,
68 // S: 'static,
69 // R1: 'static,
70 // A1: 'static + HandlerResolvable<(R1,), O, A1>,
71 // {
72 // async fn handle(
73 // &self,
74 // parameters: (R1,),
75 // additional_parameters: (A1,),
76 // state: Arc<S>,
77 // operation_state: &O,
78 // ) -> Output {
79 // todo!()
80 // }
81 // }
82
83 // #[async_trait::async_trait(?Send)]
84 // impl<R1, A1, A2, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1, A2), S, O, Output> for F
85 // where
86 // F: FnMut(R1, S, &O, A1, A2) -> Fut,
87 // Fut: Future<Output = Output>,
88 // S: 'static,
89 // R1: 'static,
90 // A1: 'static + HandlerResolvable<(R1,), O, A1>,
91 // A2: 'static + HandlerResolvable<(R1,), O, A2>,
92 // {
93 // async fn handle(
94 // &self,
95 // parameters: (R1,),
96 // additional_parameters: (A1, A2),
97 // state: Arc<S>,
98 // operation_state: &O,
99 // ) -> Output {
100 // todo!()
101 // }
102 // }
103
104 // #[async_trait::async_trait(?Send)]
105 // impl<R1, A1, A2, A3, S, O, Output, F, Fut> GiteratedHandler<(R1,), (A1, A2, A3), S, O, Output> for F
106 // where
107 // F: FnMut(R1, S, &O, A1, A2, A3) -> Fut,
108 // Fut: Future<Output = Output>,
109 // S: 'static,
110 // R1: 'static,
111 // A1: 'static + HandlerResolvable<(R1,), O, A1>,
112 // A2: 'static + HandlerResolvable<(R1,), O, A2>,
113 // A3: 'static + HandlerResolvable<(R1,), O, A3>,
114 // {
115 // async fn handle(
116 // &self,
117 // parameters: (R1,),
118 // additional_parameters: (A1, A2, A3),
119 // state: Arc<S>,
120 // operation_state: &O,
121 // ) -> Output {
122 // todo!()
123 // }
124 // }
125
126 // #[async_trait::async_trait(?Send)]
127 // impl<R1, R2, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (), S, O, Output> for F
128 // where
129 // F: FnMut(R1, R2, S, &O) -> Fut,
130 // Fut: Future<Output = Output>,
131 // S: 'static,
132 // R1: 'static,
133 // R2: 'static,
134 // {
135 // async fn handle(
136 // &self,
137 // parameters: (R1, R2),
138 // additional_parameters: (),
139 // state: Arc<S>,
140 // operation_state: &O,
141 // ) -> Output {
142 // todo!()
143 // }
144 // }
145
146 // #[async_trait::async_trait(?Send)]
147 // impl<R1, R2, A1, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (A1,), S, O, Output> for F
148 // where
149 // F: FnMut(R1, R2, S, &O, A1) -> Fut,
150 // Fut: Future<Output = Output>,
151 // S: 'static,
152 // R1: 'static,
153 // R2: 'static,
154 // A1: 'static + HandlerResolvable<(R1, R2), O, A1>,
155 // {
156 // async fn handle(
157 // &self,
158 // parameters: (R1, R2),
159 // additional_parameters: (A1,),
160 // state: Arc<S>,
161 // operation_state: &O,
162 // ) -> Output {
163 // todo!()
164 // }
165 // }
166
167 // #[async_trait::async_trait(?Send)]
168 // impl<R1, R2, A1, A2, S, O, Output, F, Fut> GiteratedHandler<(R1, R2), (A1, A2), S, O, Output> for F
169 // where
170 // F: FnMut(R1, R2, S, &O, A1, A2) -> Fut,
171 // Fut: Future<Output = Output>,
172 // S: 'static,
173 // R1: 'static,
174 // R2: 'static,
175 // A1: 'static + HandlerResolvable<(R1, R2), O, A1>,
176 // A2: 'static + HandlerResolvable<(R1, R2), O, A2>,
177 // {
178 // async fn handle(
179 // &self,
180 // parameters: (R1, R2),
181 // additional_parameters: (A1, A2),
182 // state: Arc<S>,
183 // operation_state: &O,
184 // ) -> Output {
185 // todo!()
186 // }
187 // }
188
189 // #[async_trait::async_trait(?Send)]
190 // impl<R1, R2, A1, A2, A3, S, O, Output, F, Fut>
191 // GiteratedHandler<(R1, R2), (A1, A2, A3), S, O, Output> for F
192 // where
193 // F: FnMut(R1, R2, S, &O, A1, A2, A3) -> Fut,
194 // Fut: Future<Output = Output>,
195 // S: 'static,
196 // R1: 'static,
197 // R2: 'static,
198 // A1: 'static + HandlerResolvable<(R1, R2), O, A1>,
199 // A2: 'static + HandlerResolvable<(R1, R2), O, A2>,
200 // A3: 'static + HandlerResolvable<(R1, R2), O, A3>,
201 // {
202 // async fn handle(
203 // &self,
204 // parameters: (R1, R2),
205 // additional_parameters: (A1, A2, A3),
206 // state: Arc<S>,
207 // operation_state: &O,
208 // ) -> Output {
209 // todo!()
210 // }
211 // }
212
213 // #[async_trait::async_trait(?Send)]
214 // impl<R1, R2, R3, S, O, Output, F, Fut> GiteratedHandler<(R1, R2, R3), (), S, O, Output> for F
215 // where
216 // F: FnMut(R1, R2, R3, S, &O) -> Fut,
217 // Fut: Future<Output = Output>,
218 // S: 'static,
219 // R1: 'static,
220 // R2: 'static,
221 // R3: 'static,
222 // {
223 // async fn handle(
224 // &self,
225 // parameters: (R1, R2, R3),
226 // additional_parameters: (),
227 // state: Arc<S>,
228 // operation_state: &O,
229 // ) -> Output {
230 // todo!()
231 // }
232 // }
233
234 // fn test_fn<O, A, S, V, F>(handler: F)
235 // where
236 // F: GiteratedHandler<(O, V), A, S, StackOperationState, Result<(), anyhow::Error>>,
237 // O: GiteratedObject,
238 // V: GiteratedObjectValue<Object = O>,
239 // {
240 // }
241
242 // fn other_fn() {
243 // let a = String::from("a");
244 // let test = move |object: User,
245 // value: GetValue,
246 // state: (),
247 // operation_state: &StackOperationState,
248 // authorized_user: AuthorizedUser| { async move { () } };
249
250 // let wrapper = HandlerWrapper::<(User, GetValue), _>::new((), test);
251 // }
252
253 // pub struct HandlerWrapper<P, O> {
254 // func: Box<dyn Fn(P, StackOperationState) -> LocalBoxFuture<'static, O>>,
255 // state: Arc<dyn Any + Send + Sync>,
256 // }
257
258 // impl<P, O> HandlerWrapper<P, O> {
259 // pub fn new<S, F, A>(state: S, handler: F) -> Self
260 // where
261 // F: GiteratedHandler<P, A, S, StackOperationState, O>,
262 // S: Send + Sync + 'static,
263 // A: HandlerResolvableGroup<P>,
264 // {
265 // let state = Arc::new(state);
266
267 // let func = |required: P, operation_state: StackOperationState| {
268 // // async move { handler.handle(required, (), state, &operation_state) }.boxed_local()
269 // todo!()
270 // };
271
272 // Self {
273 // func: Box::new(func),
274 // state,
275 // }
276 // }
277 // }
278
279 // #[async_trait::async_trait(?Send)]
280 // pub trait HandlerResolvable<RequiredParameters, OperationState, Output> {
281 // async fn from_handler_state(
282 // required_parameters: &RequiredParameters,
283 // operation_state: &OperationState,
284 // ) -> Output;
285 // }
286
287 // #[async_trait::async_trait(?Send)]
288 // impl HandlerResolvable<(User, GetValue), StackOperationState, Self> for Arc<GiteratedStack> {
289 // async fn from_handler_state(
290 // required_parameters: &(User, GetValue),
291 // operation_state: &StackOperationState,
292 // ) -> Self {
293 // todo!()
294 // }
295 // }
296
297 // // #[async_trait::async_trait(?Send)]
298 // // impl<O, D, T> HandlerResolvable<(O, D), StackOperationState, T> for T
299 // // where
300 // // O: GiteratedObject,
301 // // D: GiteratedOperation<O>,
302 // // T: FromOperationState<O, D>,
303 // // {
304 // // async fn from_handler_state(
305 // // required_parameters: &(O, D),
306 // // operation_state: &StackOperationState,
307 // // ) -> T {
308 // // todo!()
309 // // }
310 // // }
311
312 // #[async_trait::async_trait(?Send)]
313 // pub trait HandlerResolvableGroup<RequiredParameters> {
314 // async fn group_from_handler_state(
315 // required_parameters: &RequiredParameters,
316 // operation_state: &StackOperationState,
317 // ) -> Self;
318 // }
319
320 // #[async_trait::async_trait(?Send)]
321 // impl<RequiredParameters, A1> HandlerResolvableGroup<RequiredParameters> for (A1,)
322 // where
323 // A1: HandlerResolvable<RequiredParameters, StackOperationState, A1>,
324 // {
325 // async fn group_from_handler_state(
326 // required_parameters: &RequiredParameters,
327 // operation_state: &StackOperationState,
328 // ) -> (A1,) {
329 // (A1::from_handler_state(required_parameters, operation_state).await,)
330 // }
331 // }
332
333 // #[async_trait::async_trait(?Send)]
334 // impl<RequiredParameters, A1, A2> HandlerResolvableGroup<RequiredParameters> for (A1, A2)
335 // where
336 // A1: HandlerResolvable<RequiredParameters, StackOperationState, A1>,
337 // A2: HandlerResolvable<RequiredParameters, StackOperationState, A2>,
338 // {
339 // async fn group_from_handler_state(
340 // required_parameters: &RequiredParameters,
341 // operation_state: &StackOperationState,
342 // ) -> (A1, A2) {
343 // (
344 // A1::from_handler_state(required_parameters, operation_state).await,
345 // A2::from_handler_state(required_parameters, operation_state).await,
346 // )
347 // }
348 // }
1 use std::sync::Arc;
2
3 use giterated_models::error::OperationError;
4 use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState};
5 use tracing::trace;
6
7 use crate::{CacheKey, CacheSubstack};
8
9 pub async fn cache_updated(
10 object: AnyObject,
11 value: AnyValue,
12 state: CacheSubstack,
13 _operation_state: StackOperationState,
14 stack: Arc<GiteratedStack>,
15 ) -> Result<(), OperationError<anyhow::Error>> {
16 let object_meta = stack
17 .metadata
18 .objects
19 .get(object.kind())
20 .ok_or_else(|| OperationError::Unhandled)?;
21 let object_str = (object_meta.to_str)(object.clone());
22 let cache_key = CacheKey {
23 object: object_str,
24 value_name: value.kind().value_kind.to_string(),
25 };
26
27 let value_kind = value.kind().value_kind;
28 trace!(
29 "Beginning cache update for {}::{}",
30 object.kind(),
31 value_kind
32 );
33
34 state.cache.insert(cache_key, value).await;
35
36 trace!(
37 "Completed cache update for {}::{}",
38 object.kind(),
39 value_kind
40 );
41 Ok(())
42 }

giterated-cache/src/lib.rs

View file
@@ -1,25 +1,42 @@
1 // pub mod cache_get;
2 // pub mod cache_update;
1 use cache_get::get_cached;
2 use giterated_stack::{AnyValue, SubstackBuilder};
3 use moka::future::Cache;
4
5 use crate::cache_update::cache_updated;
6
7 pub mod cache_get;
8 pub mod cache_update;
3 9
4 10 // use giterated_stack::{ObjectValuePair, SubstackBuilder};
5 11 // use moka::future::Cache;
6 12 // use serde_json::Value;
7 13
8 // #[derive(Clone)]
9 // pub struct CacheSubstack {
10 // cache: Cache<ObjectValuePair, Value>,
11 // }
12
13 // impl Default for CacheSubstack {
14 // fn default() -> Self {
15 // Self {
16 // cache: Cache::new(20_000),
17 // }
18 // }
19 // }
20
21 // impl CacheSubstack {
22 // pub fn into_substack(self) -> SubstackBuilder<Self> {
23 // todo!()
24 // }
25 // }
14 #[derive(Hash, PartialEq, Eq)]
15 pub struct CacheKey {
16 object: String,
17 value_name: String,
18 }
19
20 #[derive(Clone)]
21 pub struct CacheSubstack {
22 cache: Cache<CacheKey, AnyValue>,
23 }
24
25 impl Default for CacheSubstack {
26 fn default() -> Self {
27 Self {
28 cache: Cache::new(20_000),
29 }
30 }
31 }
32
33 impl CacheSubstack {
34 pub fn into_substack(self) -> SubstackBuilder<Self> {
35 let mut stack = SubstackBuilder::new(self);
36
37 stack.value_change(cache_updated);
38 stack.dynamic_value(get_cached);
39
40 stack
41 }
42 }

giterated-daemon/Cargo.toml

View file
@@ -32,6 +32,7 @@ semver = {version = "1.0", features = ["serde"]}
32 32 giterated-models = { path = "../giterated-models" }
33 33 giterated-api = { path = "../../giterated-api" }
34 34 giterated-stack = { path = "../giterated-stack" }
35 giterated-cache = { path = "../giterated-cache" }
35 36 deadpool = "0.9"
36 37 bincode = "1.3"
37 38 tokio-util = {version = "0.7", features = ["rt"]}

giterated-daemon/src/database_backend/mod.rs

View file
@@ -25,7 +25,7 @@ use self::handler::{
25 25 instance_registration_request, repository_commit_before, repository_commit_by_id,
26 26 repository_diff, repository_diff_patch, repository_file_from_id, repository_file_from_path,
27 27 repository_get_branches, repository_get_statistics, repository_info,
28 repository_last_commit_of_file, repository_latest_commit, user_get_repositories,
28 repository_last_commit_of_file, user_get_repositories,
29 29 };
30 30
31 31 /// A backend implementation which attempts to resolve data from the instance's database.
@@ -75,7 +75,7 @@ impl DatabaseBackend {
75 75 .value_setting::<Repository, Visibility>()
76 76 .value_setting::<Repository, DefaultBranch>();
77 77
78 builder.value(repository_latest_commit);
78 // builder.value(repository_latest_commit);
79 79
80 80 builder
81 81 .operation(user_get_repositories)
@@ -116,13 +116,13 @@ impl MetadataProvider for DatabaseBackend {
116 116 setting: AnySetting,
117 117 setting_meta: &SettingMeta,
118 118 ) -> Result<(), anyhow::Error> {
119 if let Some(repository) = object.0.downcast_ref::<Repository>() {
119 if let Some(repository) = object.downcast_ref::<Repository>() {
120 120 sqlx::query!("INSERT INTO repository_settings VALUES ($1, $2, $3) ON CONFLICT (repository, name) DO UPDATE SET value = $3",
121 121 repository.to_string(), setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?)
122 122 .execute(&self.pool).await?;
123 123
124 124 Ok(())
125 } else if let Some(user) = object.0.downcast_ref::<User>() {
125 } else if let Some(user) = object.downcast_ref::<User>() {
126 126 sqlx::query!("INSERT INTO user_settings VALUES ($1, $2, $3) ON CONFLICT (username, name) DO UPDATE SET value = $3",
127 127 user.username, setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?)
128 128 .execute(&self.pool).await?;
@@ -139,7 +139,7 @@ impl MetadataProvider for DatabaseBackend {
139 139 _object_meta: &ObjectMeta,
140 140 setting_meta: &SettingMeta,
141 141 ) -> Result<Value, anyhow::Error> {
142 if let Some(repository) = object.0.downcast_ref::<Repository>() {
142 if let Some(repository) = object.downcast_ref::<Repository>() {
143 143 let row = sqlx::query_as!(
144 144 RepositorySettingRow,
145 145 "SELECT * FROM repository_settings WHERE repository = $1 AND name = $2",
@@ -153,7 +153,7 @@ impl MetadataProvider for DatabaseBackend {
153 153 serde_json::from_str(&row.value).context("deserializing setting from database")?;
154 154
155 155 Ok(setting)
156 } else if let Some(user) = object.0.downcast_ref::<User>() {
156 } else if let Some(user) = object.downcast_ref::<User>() {
157 157 info!("User for {}", setting_meta.name);
158 158 let row = sqlx::query_as!(
159 159 UserSettingRow,

giterated-daemon/src/main.rs

View file
@@ -1,5 +1,6 @@
1 1 use anyhow::Error;
2 2 use connection::{Connections, RawConnection};
3 use giterated_cache::CacheSubstack;
3 4 use giterated_daemon::{
4 5 authentication::AuthenticationTokenGranter,
5 6 backend::{
@@ -100,6 +101,9 @@ async fn main() -> Result<(), Error> {
100 101 let database_backend = database_backend.into_substack();
101 102 runtime.merge_builder(database_backend);
102 103
104 let cache_backend = CacheSubstack::default();
105 runtime.merge_builder(cache_backend.into_substack());
106
103 107 let runtime = Arc::new(runtime);
104 108
105 109 stack_cell

giterated-models/src/settings/operations.rs

View file
@@ -42,5 +42,5 @@ impl<O: GiteratedObject> GiteratedOperation<O> for SetSetting {
42 42 #[derive(Error, Debug, Serialize, Deserialize, Clone)]
43 43 pub enum SetSettingError {
44 44 #[error("Invalid setting `{0}` on object `{0}`")]
45 InvalidSetting(String, String)
45 InvalidSetting(String, String),
46 46 }

giterated-stack/src/lib.rs

View file
@@ -29,7 +29,7 @@ use giterated_models::{
29 29 value::{GetValue, GiteratedObjectValue},
30 30 };
31 31
32 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
32 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
33 33 pub struct ObjectOperationPair<'a> {
34 34 pub object_name: &'a str,
35 35 pub operation_name: &'a str,
@@ -45,7 +45,7 @@ impl ObjectOperationPair<'static> {
45 45 }
46 46 }
47 47
48 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
48 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
49 49 pub struct ObjectValuePair<'a> {
50 50 pub object_kind: &'a str,
51 51 pub value_kind: &'a str,
@@ -60,7 +60,7 @@ impl ObjectValuePair<'static> {
60 60 }
61 61 }
62 62
63 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
63 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
64 64 pub struct ObjectSettingPair<'a> {
65 65 pub object_kind: &'a str,
66 66 pub setting_name: &'a str,
@@ -452,19 +452,213 @@ where
452 452 }
453 453
454 454 #[derive(Clone)]
455 pub struct AnyObject(pub Arc<dyn Any + Send + Sync>);
455 pub struct AnyObject {
456 inner: Arc<dyn Any + Send + Sync>,
457 kind: &'static str,
458 }
459
460 impl AnyObject {
461 pub fn new<O: GiteratedObject + 'static>(object: O) -> Self {
462 Self {
463 inner: Arc::new(object) as _,
464 kind: O::object_name(),
465 }
466 }
467
468 pub fn new_raw(_object: Arc<dyn Any + Send + Sync>, _kind: &'static str) -> Self {
469 todo!()
470 }
471
472 pub fn kind(&self) -> &'static str {
473 self.kind
474 }
475 }
476
477 impl Deref for AnyObject {
478 type Target = dyn Any + Send + Sync;
479
480 fn deref(&self) -> &Self::Target {
481 self.inner.as_ref()
482 }
483 }
456 484
457 485 #[derive(Clone)]
458 pub struct AnyOperation(pub Arc<dyn Any + Send>);
486 pub struct AnyOperation {
487 inner: Arc<dyn Any + Send + Sync>,
488 kind: ObjectOperationPair<'static>,
489 }
490
491 impl AnyOperation {
492 pub fn new<O: GiteratedObject, D: GiteratedOperation<O> + 'static>(operation: D) -> Self {
493 Self {
494 inner: Arc::new(operation) as _,
495 kind: ObjectOperationPair::from_types::<O, D>(),
496 }
497 }
498
499 pub fn new_raw(
500 _operation: Arc<dyn Any + Send + Sync>,
501 _kind: ObjectOperationPair<'static>,
502 ) -> Self {
503 todo!()
504 }
505
506 pub fn kind(&self) -> ObjectOperationPair<'static> {
507 self.kind
508 }
509 }
510
511 impl Deref for AnyOperation {
512 type Target = dyn Any + Send + Sync;
513
514 fn deref(&self) -> &Self::Target {
515 self.inner.as_ref()
516 }
517 }
459 518
460 519 #[derive(Clone)]
461 pub struct AnySuccess(pub Arc<dyn Any + Send>);
520 pub struct AnyValue {
521 inner: Arc<dyn Any + Send + Sync>,
522 kind: ObjectValuePair<'static>,
523 }
524
525 impl AnyValue {
526 pub fn new<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static>(
527 value: V,
528 ) -> Self {
529 Self {
530 inner: Arc::new(value) as _,
531 kind: ObjectValuePair::from_types::<O, V>(),
532 }
533 }
534
535 pub fn new_raw(_value: Arc<dyn Any + Send + Sync>, _kind: ObjectValuePair<'static>) -> Self {
536 todo!()
537 }
538
539 pub fn kind(&self) -> ObjectValuePair<'static> {
540 self.kind
541 }
542 }
543
544 impl Deref for AnyValue {
545 type Target = dyn Any + Send + Sync;
546
547 fn deref(&self) -> &Self::Target {
548 self.inner.as_ref()
549 }
550 }
462 551
463 552 #[derive(Clone)]
464 pub struct AnyFailure(pub Arc<dyn Any + Send>);
553 pub struct AnySetting {
554 inner: Arc<dyn Any + Send + Sync>,
555 kind: ObjectSettingPair<'static>,
556 }
557
558 impl AnySetting {
559 pub fn new<O: GiteratedObject, S: Setting + 'static>(setting: S) -> Self {
560 Self {
561 inner: Arc::new(setting) as _,
562 kind: ObjectSettingPair::from_types::<O, S>(),
563 }
564 }
565
566 pub fn new_raw(
567 _setting: Arc<dyn Any + Send + Sync>,
568 _kind: ObjectSettingPair<'static>,
569 ) -> Self {
570 todo!()
571 }
572
573 pub fn kind(&self) -> ObjectSettingPair<'static> {
574 self.kind
575 }
576 }
577
578 impl Deref for AnySetting {
579 type Target = dyn Any + Send + Sync;
580
581 fn deref(&self) -> &Self::Target {
582 self.inner.as_ref()
583 }
584 }
465 585
466 586 #[derive(Clone)]
467 pub struct AnyValue(pub Arc<dyn Any + Send>);
587 pub struct AnySuccess(pub Arc<dyn Any + Send>);
468 588
469 589 #[derive(Clone)]
470 pub struct AnySetting(pub Arc<dyn Any + Send + Sync>);
590 pub struct AnyFailure(pub Arc<dyn Any + Send>);
591
592 /// Should be renamed.
593 ///
594 /// Allows accepting object types that are either GiteratedObject types or
595 /// AnyObject.
596 pub trait MaybeDynamicObject: Clone {
597 fn from_any(object: &AnyObject) -> Self;
598
599 fn object_name() -> &'static str;
600 }
601
602 impl<O: GiteratedObject> MaybeDynamicObject for O {
603 fn from_any(_object: &AnyObject) -> Self {
604 todo!()
605 }
606
607 fn object_name() -> &'static str {
608 <O as GiteratedObject>::object_name()
609 }
610 }
611
612 impl MaybeDynamicObject for AnyObject {
613 fn from_any(object: &AnyObject) -> Self {
614 object.clone()
615 }
616
617 fn object_name() -> &'static str {
618 "any"
619 }
620 }
621
622 pub trait MaybeDynamicValue {
623 fn from_any(value: &AnyValue) -> Self;
624 fn into_any(self) -> AnyValue;
625 fn meta() -> Option<ValueMeta>;
626
627 fn value_name() -> &'static str;
628 }
629
630 impl<V: GiteratedObjectValue> MaybeDynamicValue for V {
631 fn from_any(_object: &AnyValue) -> Self {
632 todo!()
633 }
634
635 fn value_name() -> &'static str {
636 todo!()
637 }
638
639 fn into_any(self) -> AnyValue {
640 todo!()
641 }
642
643 fn meta() -> Option<ValueMeta> {
644 todo!()
645 }
646 }
647
648 impl MaybeDynamicValue for AnyValue {
649 fn value_name() -> &'static str {
650 "any"
651 }
652
653 fn from_any(value: &AnyValue) -> Self {
654 value.clone()
655 }
656
657 fn into_any(self) -> AnyValue {
658 self
659 }
660
661 fn meta() -> Option<ValueMeta> {
662 todo!()
663 }
664 }

giterated-stack/src/meta/mod.rs

View file
@@ -141,11 +141,11 @@ impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValu
141 141 }
142 142
143 143 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error> {
144 Ok(AnyValue(Arc::new(serde_json::from_slice(buffer)?)))
144 Ok(AnyValue::new(serde_json::from_slice::<V>(buffer)?))
145 145 }
146 146
147 147 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> {
148 let value = value.0.downcast_ref::<V>().unwrap();
148 let value = value.downcast_ref::<V>().unwrap();
149 149
150 150 serde_json::to_vec(&*value)
151 151 }
@@ -157,7 +157,7 @@ impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValu
157 157 }
158 158
159 159 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool {
160 typed_get_value.0.is::<GetValueTyped<V>>()
160 typed_get_value.is::<GetValueTyped<V>>()
161 161 }
162 162 }
163 163
@@ -202,9 +202,7 @@ where
202 202 }
203 203
204 204 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error> {
205 Ok(AnyOperation(
206 Arc::new(serde_json::from_slice::<D>(buffer)?) as Arc<dyn Any + Send + Sync>
207 ))
205 Ok(AnyOperation::new(serde_json::from_slice::<D>(buffer)?))
208 206 }
209 207
210 208 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> {
@@ -237,6 +235,7 @@ impl OperationMeta {
237 235
238 236 pub struct ObjectMeta {
239 237 pub name: String,
238 pub to_str: Box<dyn Fn(AnyObject) -> String + Send + Sync>,
240 239 pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>,
241 240 pub any_is_same: fn(&dyn Any) -> bool,
242 241 }
@@ -257,13 +256,18 @@ impl<O: GiteratedObject + 'static> IntoObjectMeta for O {
257 256 }
258 257
259 258 impl ObjectMeta {
260 pub fn new<I: IntoObjectMeta + Send + Sync + 'static>() -> Self {
259 pub fn new<I: IntoObjectMeta + Send + Sync + 'static + GiteratedObject>() -> Self {
261 260 Self {
262 261 name: I::name(),
263 262 from_str: Box::new(|source| {
264 263 let object = I::from_str(source).map_err(|_| ())?;
265 264
266 Ok(AnyObject(Arc::new(object) as Arc<dyn Any + Send + Sync>))
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()
267 271 }),
268 272 any_is_same: I::any_is_same,
269 273 }
@@ -300,11 +304,11 @@ impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta
300 304 }
301 305
302 306 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
303 Ok(AnySetting(Arc::new(serde_json::from_value::<S>(value)?)))
307 Ok(AnySetting::new::<O, S>(serde_json::from_value::<S>(value)?))
304 308 }
305 309
306 310 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
307 serde_json::to_value(setting.0.downcast_ref::<S>().unwrap())
311 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
308 312 }
309 313
310 314 fn setting_updated(
@@ -316,8 +320,8 @@ impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta
316 320 async move {
317 321 stack
318 322 .setting_update(
319 object.0.downcast_ref::<O>().unwrap().clone(),
320 setting.0.downcast_ref::<S>().unwrap().clone(),
323 object.downcast_ref::<O>().unwrap().clone(),
324 setting.downcast_ref::<S>().unwrap().clone(),
321 325 operation_state,
322 326 )
323 327 .await

giterated-stack/src/stack.rs

View file
@@ -1,6 +1,7 @@
1 1 use std::any::Any;
2 2
3 3 use std::fmt::Debug;
4 use std::ops::Deref;
4 5 use std::{collections::HashMap, sync::Arc};
5 6
6 7 use giterated_models::authenticated::AuthenticatedPayload;
@@ -8,7 +9,7 @@ use giterated_models::error::{GetValueError, IntoInternalError};
8 9 use giterated_models::message::GiteratedMessage;
9 10 use giterated_models::object::NetworkAnyObject;
10 11 use giterated_models::operation::NetworkAnyOperation;
11 use giterated_models::settings::{GetSettingError, Setting, SetSettingError};
12 use giterated_models::settings::{GetSettingError, SetSettingError, Setting};
12 13 use giterated_models::value::{GetValue, GiteratedObjectValue};
13 14 use giterated_models::{
14 15 error::OperationError,
@@ -17,8 +18,8 @@ use giterated_models::{
17 18 operation::GiteratedOperation,
18 19 settings::{GetSetting, SetSetting},
19 20 };
20 use serde_json::Value;
21 use tracing::{info, trace};
21
22 use tracing::{trace, warn};
22 23
23 24 use crate::handler::HandlerTree;
24 25 use crate::provider::MetadataProvider;
@@ -30,7 +31,7 @@ use crate::{
30 31
31 32 pub type OperationHandler = HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure>;
32 33
33 pub type ValueGetter = HandlerWrapper<(AnyObject,), AnyValue, AnyFailure>;
34 pub type ValueGetter = HandlerWrapper<(AnyObject, String), AnyValue, AnyFailure>;
34 35
35 36 pub type SettingGetter = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure>;
36 37
@@ -102,13 +103,50 @@ impl GiteratedStack {
102 103 trace!("value updated {}::{}", O::object_name(), V::value_name());
103 104 let target = ObjectValuePair::from_types::<O, V>();
104 105
106 let object = AnyObject::new(object);
107 let value = AnyValue::new(new_value);
108
109 // First, resolve a handler for the exact object value pair
105 110 if let Some(handler) = self.value_change.get(&target) {
106 111 // TODO
107 112 let _ = handler
108 .handle(
109 (AnyObject(Arc::new(object)), AnyValue(Arc::new(new_value))),
110 operation_state.clone(),
111 )
113 .handle((object.clone(), value.clone()), operation_state.clone())
114 .await;
115 }
116
117 // We need to resolve for `any` object and `any` value combination
118 let target = ObjectValuePair {
119 object_kind: "any",
120 value_kind: V::value_name(),
121 };
122 if let Some(handler) = self.value_change.get(&target) {
123 // TODO
124 let _ = handler
125 .handle((object.clone(), value.clone()), operation_state.clone())
126 .await;
127 }
128
129 let target = ObjectValuePair {
130 object_kind: O::object_name(),
131 value_kind: "any",
132 };
133 if let Some(handler) = self.value_change.get(&target) {
134 // TODO
135 let _ = handler
136 .handle((object.clone(), value.clone()), operation_state.clone())
137 .await;
138 }
139
140 // Now resolve for both `any`
141
142 let target = ObjectValuePair {
143 object_kind: "any",
144 value_kind: "any",
145 };
146 if let Some(handler) = self.value_change.get(&target) {
147 // TODO
148 let _ = handler
149 .handle((object.clone(), value.clone()), operation_state.clone())
112 150 .await;
113 151 }
114 152 }
@@ -128,10 +166,7 @@ impl GiteratedStack {
128 166 if let Some(handler) = self.setting_change.get(&target) {
129 167 let _ = handler
130 168 .handle(
131 (
132 AnyObject(Arc::new(object)),
133 AnySetting(Arc::new(new_setting)),
134 ),
169 (AnyObject::new(object), AnySetting::new::<O, S>(new_setting)),
135 170 operation_state.clone(),
136 171 )
137 172 .await;
@@ -171,9 +206,9 @@ impl GiteratedStack {
171 206
172 207 let result = provider
173 208 .write(
174 AnyObject(Arc::new(object.clone())),
209 AnyObject::new(object.clone()),
175 210 object_meta,
176 AnySetting(Arc::new(setting)),
211 AnySetting::new::<O, S>(setting),
177 212 setting_meta,
178 213 )
179 214 .await
@@ -213,11 +248,7 @@ impl GiteratedStack {
213 248 .ok_or_else(|| OperationError::Unhandled)?;
214 249
215 250 let value = provider
216 .read(
217 AnyObject(Arc::new(object.clone())),
218 object_meta,
219 setting_meta,
220 )
251 .read(AnyObject::new(object.clone()), object_meta, setting_meta)
221 252 .await
222 253 .as_internal_error_with_context(format!("getting setting {}", S::name()))?;
223 254
@@ -367,7 +398,13 @@ impl GiteratedStack {
367 398 setting_name: &operation.setting_name,
368 399 })
369 400 // TODO: Check this
370 .ok_or(OperationError::Operation(serde_json::to_vec(&SetSettingError::InvalidSetting(operation.setting_name.clone(), object_type.clone())).as_internal_error()?))?;
401 .ok_or(OperationError::Operation(
402 serde_json::to_vec(&SetSettingError::InvalidSetting(
403 operation.setting_name.clone(),
404 object_type.clone(),
405 ))
406 .as_internal_error()?,
407 ))?;
371 408
372 409 let setting = (setting_meta.deserialize)(operation.value)
373 410 .as_internal_error_with_context(format!(
@@ -382,7 +419,7 @@ impl GiteratedStack {
382 419 );
383 420
384 421 for provider in self.metadata_providers.iter() {
385 if provider.provides_for(object.0.as_ref()) {
422 if provider.provides_for(object.deref()) {
386 423 trace!(
387 424 "Resolved setting provider for setting {} for object {}",
388 425 operation.setting_name,
@@ -506,45 +543,175 @@ impl GiteratedStack {
506 543 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
507 544 trace!("Handling network get_value for {}", operation.value_name);
508 545
509 let value_meta = self
510 .metadata
511 .values
512 .get(&ObjectValuePair {
513 object_kind: &object_kind,
514 value_kind: &operation.value_name,
515 })
516 .ok_or_else(|| OperationError::Unhandled)?;
546 // We first attempt generic handlers
547 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
548 object_kind: "any",
549 value_kind: &operation.value_name,
550 }) {
551 match handler
552 .handle(
553 (object.clone(), operation.value_name.clone()),
554 operation_state.clone(),
555 )
556 .await
557 {
558 Ok(success) => {
559 // Resolve the metadata to serialize
560 let value_meta = self
561 .metadata
562 .values
563 .get(&success.kind())
564 .ok_or_else(|| OperationError::Unhandled)?;
565
566 return Ok((value_meta.serialize)(success).as_internal_error()?);
567 }
568 Err(err) => {
569 match err {
570 OperationError::Operation(operation_error) => {
571 // This DOES result in an early return, because it was handled
572 let error: &GetValueError = operation_error.0.downcast_ref().unwrap();
573
574 return Err(OperationError::Operation(
575 serde_json::to_vec(&error).as_internal_error()?,
576 ));
577 }
578 OperationError::Internal(internal) => {
579 // This DOES NOT result in an early return
580 warn!("An internal error occurred during a failable handler operation. {:?}", internal);
581 }
582 OperationError::Unhandled => {
583 // This DOES NOT result in an early return
584 }
585 }
586 }
587 }
588 }
589 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
590 object_kind: &object_kind,
591 value_kind: "any",
592 }) {
593 match handler
594 .handle(
595 (object.clone(), operation.value_name.clone()),
596 operation_state.clone(),
597 )
598 .await
599 {
600 Ok(success) => {
601 // Resolve the metadata to serialize
602 let value_meta = self
603 .metadata
604 .values
605 .get(&success.kind())
606 .ok_or_else(|| OperationError::Unhandled)?;
517 607
518 for (target, getter) in self.value_getters.iter() {
519 if target.object_kind != object_kind {
520 continue;
608 return Ok((value_meta.serialize)(success).as_internal_error()?);
609 }
610 Err(err) => {
611 match err {
612 OperationError::Operation(operation_error) => {
613 // This DOES result in an early return, because it was handled
614 let error: &GetValueError = operation_error.0.downcast_ref().unwrap();
615
616 return Err(OperationError::Operation(
617 serde_json::to_vec(&error).as_internal_error()?,
618 ));
619 }
620 OperationError::Internal(internal) => {
621 // This DOES NOT result in an early return
622 warn!("An internal error occurred during a failable handler operation. {:?}", internal);
623 }
624 OperationError::Unhandled => {
625 // This DOES NOT result in an early return
626 }
627 }
628 }
521 629 }
630 }
631 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
632 object_kind: "any",
633 value_kind: "any",
634 }) {
635 match handler
636 .handle(
637 (object.clone(), operation.value_name.clone()),
638 operation_state.clone(),
639 )
640 .await
641 {
642 Ok(success) => {
643 // Resolve the metadata to serialize
644 let value_meta = self
645 .metadata
646 .values
647 .get(&success.kind())
648 .ok_or_else(|| OperationError::Unhandled)?;
522 649
523 if target.value_kind != operation.value_name {
524 continue;
650 return Ok((value_meta.serialize)(success).as_internal_error()?);
651 }
652 Err(err) => {
653 match err {
654 OperationError::Operation(operation_error) => {
655 // This DOES result in an early return, because it was handled
656 let error: &GetValueError = operation_error.0.downcast_ref().unwrap();
657
658 return Err(OperationError::Operation(
659 serde_json::to_vec(&error).as_internal_error()?,
660 ));
661 }
662 OperationError::Internal(internal) => {
663 // This DOES NOT result in an early return
664 warn!("An internal error occurred during a failable handler operation. {:?}", internal);
665 }
666 OperationError::Unhandled => {
667 // This DOES NOT result in an early return
668 }
669 }
670 }
525 671 }
672 }
526 673
527 return match getter
528 .handle((object.clone(),), operation_state.clone())
674 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
675 object_kind: &object_kind,
676 value_kind: &operation.value_name,
677 }) {
678 match handler
679 .handle(
680 (object.clone(), operation.value_name.clone()),
681 operation_state.clone(),
682 )
529 683 .await
530 684 {
531 685 Ok(success) => {
532 // Serialize success, which is the value type itself
533 let serialized = (value_meta.serialize)(success).as_internal_error()?;
686 // Resolve the metadata to serialize
687 let value_meta = self
688 .metadata
689 .values
690 .get(&success.kind())
691 .ok_or_else(|| OperationError::Unhandled)?;
534 692
535 Ok(serialized)
693 return Ok((value_meta.serialize)(success).as_internal_error()?);
536 694 }
537 Err(err) => Err(match err {
538 OperationError::Operation(failure) => {
539 // Failure is sourced from GetValue operation, but this is hardcoded for now
540 let failure: &GetValueError = failure.0.downcast_ref().unwrap();
541
542 OperationError::Operation(serde_json::to_vec(&failure).as_internal_error()?)
695 Err(err) => {
696 match err {
697 OperationError::Operation(operation_error) => {
698 // This DOES result in an early return, because it was handled
699 let error: &GetValueError = operation_error.0.downcast_ref().unwrap();
700
701 return Err(OperationError::Operation(
702 serde_json::to_vec(&error).as_internal_error()?,
703 ));
704 }
705 OperationError::Internal(internal) => {
706 // This DOES NOT result in an early return
707 warn!("An internal error occurred during a failable handler operation. {:?}", internal);
708 }
709 OperationError::Unhandled => {
710 // This DOES NOT result in an early return
711 }
543 712 }
544 OperationError::Internal(internal) => OperationError::Internal(internal),
545 OperationError::Unhandled => OperationError::Unhandled,
546 }),
547 };
713 }
714 }
548 715 }
549 716
550 717 Err(OperationError::Unhandled)
@@ -564,7 +731,7 @@ impl GiteratedStack {
564 731 );
565 732
566 733 for provider in self.metadata_providers.iter() {
567 if provider.provides_for(object.0.as_ref()) {
734 if provider.provides_for(object.deref()) {
568 735 let setting_meta = self
569 736 .metadata
570 737 .settings
@@ -671,13 +838,12 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
671 838 D::Failure: Clone,
672 839 {
673 840 // Erase object and operation types.
674 let object = AnyObject(Arc::new(in_object.clone()) as Arc<dyn Any + Send + Sync>);
675 let operation = AnyOperation(Arc::new(payload) as Arc<dyn Any + Send + Sync>);
841 let object = AnyObject::new(in_object.clone());
842 let operation = AnyOperation::new(payload);
676 843
677 844 // We need to hijack get_value, set_setting, and get_setting.
678 845 if operation_name == "get_value" {
679 846 let get_value = operation
680 .0
681 847 .downcast_ref::<GetValue>()
682 848 .ok_or_else(|| OperationError::Unhandled)?;
683 849
@@ -713,7 +879,10 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
713 879 );
714 880
715 881 return match getter
716 .handle((object.clone(),), operation_state.clone())
882 .handle(
883 (object.clone(), get_value.value_name.clone()),
884 operation_state.clone(),
885 )
717 886 .await
718 887 {
719 888 Ok(success) => Ok(*(Box::new((value_meta.serialize)(success).unwrap())
@@ -735,8 +904,8 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
735 904 }),
736 905 };
737 906 }
738 } else if operation.0.is::<GetSetting>() {
739 let get_setting: &GetSetting = operation.0.downcast_ref().unwrap();
907 } else if operation.is::<GetSetting>() {
908 let get_setting: &GetSetting = operation.downcast_ref().unwrap();
740 909 let setting_name = get_setting.setting_name.clone();
741 910
742 911 let raw_result = self
@@ -754,7 +923,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
754 923 // let serialized = (setting_meta.serialize)(success).unwrap();
755 924
756 925 // Ok(serde_json::to_vec(&serialized).unwrap())
757 Ok(success.0.downcast_ref::<D::Success>().unwrap().clone())
926 Ok(success.downcast_ref::<D::Success>().unwrap().clone())
758 927 }
759 928 Err(err) => Err(match err {
760 929 OperationError::Operation(failure) => {
@@ -771,9 +940,9 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
771 940 OperationError::Unhandled => OperationError::Unhandled,
772 941 }),
773 942 };
774 } else if operation.0.is::<SetSetting>() {
943 } else if operation.is::<SetSetting>() {
775 944 todo!()
776 } else if operation.0.is::<ObjectRequest>() {
945 } else if operation.is::<ObjectRequest>() {
777 946 todo!()
778 947 }
779 948
@@ -841,10 +1010,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
841 1010 for (_object_name, object_meta) in self.metadata.objects.iter() {
842 1011 if let Ok(object) = (object_meta.from_str)(object_str) {
843 1012 return Ok(unsafe {
844 Object::new_unchecked(
845 object.0.downcast_ref::<O>().unwrap().clone(),
846 self.clone(),
847 )
1013 Object::new_unchecked(object.downcast_ref::<O>().unwrap().clone(), self.clone())
848 1014 });
849 1015 }
850 1016 }

giterated-stack/src/substack.rs

View file
@@ -14,8 +14,9 @@ use tracing::{info, trace};
14 14 use crate::{
15 15 handler::HandlerWrapper, provider::MetadataProvider, AnyFailure, AnyObject, AnyOperation,
16 16 AnySetting, AnySuccess, AnyValue, GiteratedStack, GiteratedStackState, IntoGiteratedHandler,
17 ObjectOperationPair, ObjectSettingPair, ObjectValuePair, OperationHandler, RuntimeMetadata,
18 SettingChange, SettingGetter, StackOperationState, ValueChange, ValueGetter,
17 MaybeDynamicObject, MaybeDynamicValue, ObjectOperationPair, ObjectSettingPair, ObjectValuePair,
18 OperationHandler, RuntimeMetadata, SettingChange, SettingGetter, StackOperationState,
19 ValueChange, ValueGetter,
19 20 };
20 21
21 22 pub struct SubstackBuilder<S: GiteratedStackState> {
@@ -75,8 +76,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
75 76 |(any_object, any_operation): &(AnyObject, AnyOperation),
76 77 _state: &StackOperationState| {
77 78 Ok((
78 any_object.0.downcast_ref::<O>().unwrap().clone(),
79 any_operation.0.downcast_ref::<D>().unwrap().clone(),
79 any_object.downcast_ref::<O>().unwrap().clone(),
80 any_operation.downcast_ref::<D>().unwrap().clone(),
80 81 ))
81 82 },
82 83 );
@@ -172,8 +173,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
172 173 );
173 174 let object = object.clone();
174 175 async move {
175 let object = object.0.downcast_ref::<O>().unwrap();
176 let setting = setting.0.downcast_ref::<T>().unwrap();
176 let object = object.downcast_ref::<O>().unwrap();
177 let setting = setting.downcast_ref::<T>().unwrap();
177 178 stack
178 179 .value_update(object.clone(), setting.clone(), &operation_state)
179 180 .await;
@@ -187,6 +188,7 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
187 188 let wrapped = HandlerWrapper::new(
188 189 self.state.clone(),
189 190 |object: AnyObject,
191 _name: String,
190 192 _state: _,
191 193 _operation_state: StackOperationState,
192 194 stack: Arc<GiteratedStack>| {
@@ -194,10 +196,10 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
194 196 let object = object.clone();
195 197 async move {
196 198 match stack
197 .new_get_setting::<O, T>(object.0.downcast_ref().unwrap())
199 .new_get_setting::<O, T>(object.downcast_ref().unwrap())
198 200 .await
199 201 {
200 Ok(setting) => Ok(AnyValue(Arc::new(setting))),
202 Ok(setting) => Ok(AnyValue::new(setting)),
201 203 Err(err) => {
202 204 panic!("Error: {:?}", err);
203 205 }
@@ -219,30 +221,29 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
219 221 /// # Type Registration
220 222 /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified
221 223 /// object type. It will **not** register the object type automatically.
222 pub fn value<O, V, A, F, E>(&mut self, handler: F) -> &mut Self
224 pub fn dynamic_value<O, A, F>(&mut self, handler: F) -> &mut Self
223 225 where
224 O: GiteratedObject + 'static,
225 V: GiteratedObjectValue<Object = O> + 'static + Clone,
226 F: IntoGiteratedHandler<(O,), A, S, StackOperationState, Result<V, OperationError<E>>>
227 + Send
226 O: MaybeDynamicObject + 'static,
227 F: IntoGiteratedHandler<
228 (O, String),
229 A,
230 S,
231 StackOperationState,
232 Result<AnyValue, OperationError<anyhow::Error>>,
233 > + Send
228 234 + Sync,
229 E: Into<anyhow::Error> + 'static + std::fmt::Debug + Clone,
230 235 F: 'static,
231 236 {
232 237 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
233 238
234 239 let wrapped = wrapped.map(
235 |(any_object,): &(AnyObject,), _state: &StackOperationState| {
236 Ok((any_object
237 .0
238 .downcast_ref::<O>()
239 .ok_or_else(|| OperationError::Internal(DowncastError.into()))?
240 .clone(),))
240 |(any_object, name): &(AnyObject, String), _state: &StackOperationState| {
241 Ok((O::from_any(any_object), name.clone()))
241 242 },
242 243 );
243 244
244 245 let wrapped = wrapped.map_return(|ret_val, _state| match ret_val {
245 Ok(success) => Ok(AnyValue(Arc::new(success))),
246 Ok(success) => Ok(success.into_any()),
246 247 Err(err) => Err(match err {
247 248 OperationError::Operation(failure) => OperationError::Internal(failure.into()),
248 249 OperationError::Internal(err) => OperationError::Internal(err),
@@ -252,17 +253,20 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
252 253
253 254 assert!(self
254 255 .value_getters
255 .insert(ObjectValuePair::from_types::<O, V>(), wrapped)
256 .insert(
257 ObjectValuePair {
258 object_kind: O::object_name(),
259 value_kind: "any"
260 },
261 wrapped
262 )
256 263 .is_none());
257 264
258 self.metadata.register_value::<O, V>();
259
260 265 self
261 266 }
262 267
263 268 pub fn value_change<O, A, F, V>(&mut self, handler: F) -> &mut Self
264 269 where
265 O: GiteratedObject + 'static,
266 270 F: IntoGiteratedHandler<
267 271 (O, V),
268 272 A,
@@ -271,8 +275,8 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
271 275 Result<(), OperationError<anyhow::Error>>,
272 276 > + Send
273 277 + Sync,
274 V: GiteratedObjectValue<Object = O> + Clone + 'static,
275 O: 'static,
278 V: MaybeDynamicValue + Clone + 'static,
279 O: 'static + MaybeDynamicObject,
276 280 V: 'static,
277 281 F: 'static,
278 282 {
@@ -280,24 +284,19 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
280 284
281 285 let wrapped = wrapped.map(
282 286 |(any_object, any_value): &(AnyObject, AnyValue), _state: &StackOperationState| {
283 Ok((
284 any_object
285 .0
286 .downcast_ref::<O>()
287 .ok_or_else(|| OperationError::Internal(DowncastError.into()))?
288 .clone(),
289 any_value
290 .0
291 .downcast_ref::<V>()
292 .ok_or_else(|| OperationError::Internal(DowncastError.into()))?
293 .clone(),
294 ))
287 Ok((O::from_any(any_object), V::from_any(any_value)))
295 288 },
296 289 );
297 290
298 291 assert!(self
299 292 .value_change
300 .insert(ObjectValuePair::from_types::<O, V>(), wrapped)
293 .insert(
294 ObjectValuePair {
295 object_kind: O::object_name(),
296 value_kind: V::value_name()
297 },
298 wrapped
299 )
301 300 .is_none());
302 301
303 302 self