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

ambee/giterated

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

Re-expose Operation State in generics.

This is the worst code I have ever written. I hate the way this changes everything. ugh.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90db3e2

Showing ⁨⁨23⁩ changed files⁩ with ⁨⁨858⁩ insertions⁩ and ⁨⁨1383⁩ deletions⁩

Cargo.lock

View file
@@ -321,33 +321,6 @@ dependencies = [
321 321 ]
322 322
323 323 [[package]]
324 name = "color-eyre"
325 version = "0.6.2"
326 source = "registry+https://github.com/rust-lang/crates.io-index"
327 checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
328 dependencies = [
329 "backtrace",
330 "color-spantrace",
331 "eyre",
332 "indenter",
333 "once_cell",
334 "owo-colors",
335 "tracing-error",
336 ]
337
338 [[package]]
339 name = "color-spantrace"
340 version = "0.2.0"
341 source = "registry+https://github.com/rust-lang/crates.io-index"
342 checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
343 dependencies = [
344 "once_cell",
345 "owo-colors",
346 "tracing-core",
347 "tracing-error",
348 ]
349
350 [[package]]
351 324 name = "const-oid"
352 325 version = "0.9.5"
353 326 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -475,18 +448,6 @@ dependencies = [
475 448 ]
476 449
477 450 [[package]]
478 name = "deadpool"
479 version = "0.10.0"
480 source = "registry+https://github.com/rust-lang/crates.io-index"
481 checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490"
482 dependencies = [
483 "async-trait",
484 "deadpool-runtime",
485 "num_cpus",
486 "tokio",
487 ]
488
489 [[package]]
490 451 name = "deadpool-runtime"
491 452 version = "0.1.3"
492 453 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -588,16 +549,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
588 549 checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
589 550
590 551 [[package]]
591 name = "eyre"
592 version = "0.6.8"
593 source = "registry+https://github.com/rust-lang/crates.io-index"
594 checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
595 dependencies = [
596 "indenter",
597 "once_cell",
598 ]
599
600 [[package]]
601 552 name = "fastrand"
602 553 version = "2.0.1"
603 554 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -787,31 +738,6 @@ dependencies = [
787 738 ]
788 739
789 740 [[package]]
790 name = "giterated-api"
791 version = "0.1.0"
792 dependencies = [
793 "anyhow",
794 "async-trait",
795 "bincode",
796 "chrono",
797 "color-eyre",
798 "deadpool 0.10.0",
799 "futures-util",
800 "giterated-models",
801 "jsonwebtoken",
802 "rand",
803 "reqwest",
804 "semver",
805 "serde",
806 "serde_json",
807 "thiserror",
808 "tokio",
809 "tokio-tungstenite",
810 "tracing",
811 "tracing-subscriber",
812 ]
813
814 [[package]]
815 741 name = "giterated-cache"
816 742 version = "0.1.0"
817 743 dependencies = [
@@ -840,10 +766,9 @@ dependencies = [
840 766 "base64 0.21.4",
841 767 "bincode",
842 768 "chrono",
843 "deadpool 0.9.5",
769 "deadpool",
844 770 "futures-util",
845 771 "git2",
846 "giterated-api",
847 772 "giterated-cache",
848 773 "giterated-models",
849 774 "giterated-protocol",
@@ -896,7 +821,10 @@ name = "giterated-protocol"
896 821 version = "0.1.0"
897 822 dependencies = [
898 823 "giterated-stack",
824 "rand",
825 "rsa",
899 826 "serde",
827 "serde_json",
900 828 "tracing",
901 829 ]
902 830
@@ -1076,20 +1004,6 @@ dependencies = [
1076 1004 ]
1077 1005
1078 1006 [[package]]
1079 name = "hyper-rustls"
1080 version = "0.24.1"
1081 source = "registry+https://github.com/rust-lang/crates.io-index"
1082 checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
1083 dependencies = [
1084 "futures-util",
1085 "http",
1086 "hyper",
1087 "rustls",
1088 "tokio",
1089 "tokio-rustls",
1090 ]
1091
1092 [[package]]
1093 1007 name = "hyper-tls"
1094 1008 version = "0.5.0"
1095 1009 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1136,12 +1050,6 @@ dependencies = [
1136 1050 ]
1137 1051
1138 1052 [[package]]
1139 name = "indenter"
1140 version = "0.3.3"
1141 source = "registry+https://github.com/rust-lang/crates.io-index"
1142 checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
1143
1144 [[package]]
1145 1053 name = "indexmap"
1146 1054 version = "1.9.3"
1147 1055 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1586,12 +1494,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1586 1494 checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
1587 1495
1588 1496 [[package]]
1589 name = "owo-colors"
1590 version = "3.5.0"
1591 source = "registry+https://github.com/rust-lang/crates.io-index"
1592 checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
1593
1594 [[package]]
1595 1497 name = "parking_lot"
1596 1498 version = "0.12.1"
1597 1499 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1820,7 +1722,6 @@ dependencies = [
1820 1722 "http",
1821 1723 "http-body",
1822 1724 "hyper",
1823 "hyper-rustls",
1824 1725 "hyper-tls",
1825 1726 "ipnet",
1826 1727 "js-sys",
@@ -1830,21 +1731,17 @@ dependencies = [
1830 1731 "once_cell",
1831 1732 "percent-encoding",
1832 1733 "pin-project-lite",
1833 "rustls",
1834 "rustls-pemfile",
1835 1734 "serde",
1836 1735 "serde_json",
1837 1736 "serde_urlencoded",
1838 1737 "system-configuration",
1839 1738 "tokio",
1840 1739 "tokio-native-tls",
1841 "tokio-rustls",
1842 1740 "tower-service",
1843 1741 "url",
1844 1742 "wasm-bindgen",
1845 1743 "wasm-bindgen-futures",
1846 1744 "web-sys",
1847 "webpki-roots",
1848 1745 "winreg",
1849 1746 ]
1850 1747
@@ -1921,49 +1818,6 @@ dependencies = [
1921 1818 ]
1922 1819
1923 1820 [[package]]
1924 name = "rustls"
1925 version = "0.21.7"
1926 source = "registry+https://github.com/rust-lang/crates.io-index"
1927 checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
1928 dependencies = [
1929 "log",
1930 "ring",
1931 "rustls-webpki",
1932 "sct",
1933 ]
1934
1935 [[package]]
1936 name = "rustls-native-certs"
1937 version = "0.6.3"
1938 source = "registry+https://github.com/rust-lang/crates.io-index"
1939 checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
1940 dependencies = [
1941 "openssl-probe",
1942 "rustls-pemfile",
1943 "schannel",
1944 "security-framework",
1945 ]
1946
1947 [[package]]
1948 name = "rustls-pemfile"
1949 version = "1.0.3"
1950 source = "registry+https://github.com/rust-lang/crates.io-index"
1951 checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
1952 dependencies = [
1953 "base64 0.21.4",
1954 ]
1955
1956 [[package]]
1957 name = "rustls-webpki"
1958 version = "0.101.6"
1959 source = "registry+https://github.com/rust-lang/crates.io-index"
1960 checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
1961 dependencies = [
1962 "ring",
1963 "untrusted",
1964 ]
1965
1966 [[package]]
1967 1821 name = "ryu"
1968 1822 version = "1.0.15"
1969 1823 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1994,16 +1848,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1994 1848 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
1995 1849
1996 1850 [[package]]
1997 name = "sct"
1998 version = "0.7.0"
1999 source = "registry+https://github.com/rust-lang/crates.io-index"
2000 checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
2001 dependencies = [
2002 "ring",
2003 "untrusted",
2004 ]
2005
2006 [[package]]
2007 1851 name = "secrecy"
2008 1852 version = "0.8.0"
2009 1853 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2638,16 +2482,6 @@ dependencies = [
2638 2482 ]
2639 2483
2640 2484 [[package]]
2641 name = "tokio-rustls"
2642 version = "0.24.1"
2643 source = "registry+https://github.com/rust-lang/crates.io-index"
2644 checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
2645 dependencies = [
2646 "rustls",
2647 "tokio",
2648 ]
2649
2650 [[package]]
2651 2485 name = "tokio-stream"
2652 2486 version = "0.1.14"
2653 2487 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2666,10 +2500,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
2666 2500 dependencies = [
2667 2501 "futures-util",
2668 2502 "log",
2669 "rustls",
2670 "rustls-native-certs",
2671 2503 "tokio",
2672 "tokio-rustls",
2673 2504 "tungstenite",
2674 2505 ]
2675 2506
@@ -2764,16 +2595,6 @@ dependencies = [
2764 2595 ]
2765 2596
2766 2597 [[package]]
2767 name = "tracing-error"
2768 version = "0.2.0"
2769 source = "registry+https://github.com/rust-lang/crates.io-index"
2770 checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
2771 dependencies = [
2772 "tracing",
2773 "tracing-subscriber",
2774 ]
2775
2776 [[package]]
2777 2598 name = "tracing-log"
2778 2599 version = "0.1.3"
2779 2600 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2823,7 +2644,6 @@ dependencies = [
2823 2644 "httparse",
2824 2645 "log",
2825 2646 "rand",
2826 "rustls",
2827 2647 "sha1",
2828 2648 "thiserror",
2829 2649 "url",
@@ -3041,12 +2861,6 @@ dependencies = [
3041 2861 ]
3042 2862
3043 2863 [[package]]
3044 name = "webpki-roots"
3045 version = "0.25.2"
3046 source = "registry+https://github.com/rust-lang/crates.io-index"
3047 checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
3048
3049 [[package]]
3050 2864 name = "whoami"
3051 2865 version = "1.4.1"
3052 2866 source = "registry+https://github.com/rust-lang/crates.io-index"

giterated-cache/src/cache_get.rs

View file
@@ -15,10 +15,8 @@
15 15 // todo!()
16 16 // }
17 17
18 use std::sync::Arc;
19
20 18 use giterated_models::error::OperationError;
21 use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState};
19 use giterated_stack::{AnyObject, AnyValue, GiteratedStack};
22 20 use tracing::trace;
23 21
24 22 use crate::{CacheKey, CacheSubstack};
@@ -27,8 +25,7 @@ pub async fn get_cached(
27 25 object: AnyObject,
28 26 value_kind: String,
29 27 cache: CacheSubstack,
30 _operation_state: StackOperationState,
31 stack: Arc<GiteratedStack>,
28 stack: GiteratedStack,
32 29 ) -> Result<AnyValue, OperationError<anyhow::Error>> {
33 30 let object_meta = stack
34 31 .metadata

giterated-cache/src/cache_update.rs

View file
@@ -1,7 +1,5 @@
1 use std::sync::Arc;
2
3 1 use giterated_models::error::OperationError;
4 use giterated_stack::{AnyObject, AnyValue, GiteratedStack, StackOperationState};
2 use giterated_stack::{AnyObject, AnyValue, GiteratedStack};
5 3 use tracing::trace;
6 4
7 5 use crate::{CacheKey, CacheSubstack};
@@ -10,8 +8,7 @@ pub async fn cache_updated(
10 8 object: AnyObject,
11 9 value: AnyValue,
12 10 state: CacheSubstack,
13 _operation_state: StackOperationState,
14 stack: Arc<GiteratedStack>,
11 stack: GiteratedStack,
15 12 ) -> Result<(), OperationError<anyhow::Error>> {
16 13 let object_meta = stack
17 14 .metadata

giterated-cache/src/lib.rs

View file
@@ -1,5 +1,5 @@
1 1 use cache_get::get_cached;
2 use giterated_stack::{AnyValue, SubstackBuilder};
2 use giterated_stack::{AnyValue, StackOperationState, SubstackBuilder};
3 3 use moka::future::Cache;
4 4
5 5 use crate::cache_update::cache_updated;
@@ -31,7 +31,7 @@ impl Default for CacheSubstack {
31 31 }
32 32
33 33 impl CacheSubstack {
34 pub fn into_substack(self) -> SubstackBuilder<Self> {
34 pub fn into_substack(self) -> SubstackBuilder<Self, StackOperationState> {
35 35 let mut stack = SubstackBuilder::new(self);
36 36
37 37 stack.value_change(cache_updated);

giterated-daemon/Cargo.toml

View file
@@ -30,7 +30,6 @@ argon2 = "0.5"
30 30 aes-gcm = "0.10"
31 31 semver = {version = "1.0", features = ["serde"]}
32 32 giterated-models = { path = "../giterated-models" }
33 giterated-api = { path = "../../giterated-api" }
34 33 giterated-stack = { path = "../giterated-stack" }
35 34 giterated-cache = { path = "../giterated-cache" }
36 35 giterated-protocol = { path = "../giterated-protocol" }

giterated-daemon/src/backend/git.rs

View file
@@ -153,7 +153,7 @@ pub struct GitBackend {
153 153 pub pg_pool: PgPool,
154 154 pub repository_folder: String,
155 155 pub instance: Instance,
156 pub stack: Arc<OnceCell<Arc<GiteratedStack>>>,
156 pub stack: Arc<OnceCell<GiteratedStack>>,
157 157 }
158 158
159 159 impl GitBackend {
@@ -161,7 +161,7 @@ impl GitBackend {
161 161 pg_pool: &PgPool,
162 162 repository_folder: &str,
163 163 instance: impl ToOwned<Owned = Instance>,
164 stack: Arc<OnceCell<Arc<GiteratedStack>>>,
164 stack: Arc<OnceCell<GiteratedStack>>,
165 165 ) -> Self {
166 166 let instance = instance.to_owned();
167 167

giterated-daemon/src/backend/settings.rs

View file
@@ -15,7 +15,7 @@ use super::MetadataBackend;
15 15
16 16 pub struct DatabaseSettings {
17 17 pub pg_pool: PgPool,
18 pub stack: Arc<OnceCell<Arc<GiteratedStack>>>,
18 pub stack: Arc<OnceCell<GiteratedStack>>,
19 19 }
20 20
21 21 #[async_trait::async_trait]

giterated-daemon/src/client.rs

View file
@@ -1,13 +1,10 @@
1 use std::sync::Arc;
2
3 1 use futures_util::{SinkExt, StreamExt};
4 2 use giterated_models::{
5 authenticated::AuthenticatedPayload,
6 3 error::{IntoInternalError, OperationError},
7 4 instance::Instance,
8 5 object_backend::ObjectBackend,
9 6 };
10 use giterated_protocol::{NetworkedObject, NetworkedOperation};
7 use giterated_protocol::{AuthenticatedPayload, NetworkedObject, NetworkedOperation};
11 8 use giterated_stack::{GiteratedStack, StackOperationState};
12 9 use tokio::net::TcpStream;
13 10 use tokio_tungstenite::{tungstenite::Message, WebSocketStream};
@@ -15,7 +12,7 @@ use tokio_tungstenite::{tungstenite::Message, WebSocketStream};
15 12 pub async fn client_wrapper(
16 13 our_instance: Instance,
17 14 mut socket: WebSocketStream<TcpStream>,
18 runtime: Arc<GiteratedStack>,
15 runtime: GiteratedStack,
19 16 ) {
20 17 loop {
21 18 let message = socket.next().await;
@@ -88,7 +85,7 @@ pub async fn client_wrapper(
88 85 pub async fn handle_client_message(
89 86 payload: AuthenticatedPayload,
90 87 operation_state: StackOperationState,
91 runtime: Arc<GiteratedStack>,
88 runtime: GiteratedStack,
92 89 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
93 90 let mut networked_object = runtime
94 91 .get_object::<NetworkedObject>(&payload.object, &operation_state)

giterated-daemon/src/database_backend/handler.rs

View file
@@ -1,5 +1,3 @@
1 use std::sync::Arc;
2
3 1 use giterated_models::{
4 2 authenticated::UserAuthenticationToken,
5 3 error::{InstanceError, IntoInternalError, OperationError, RepositoryError, UserError},
@@ -17,7 +15,7 @@ use giterated_models::{
17 15 },
18 16 user::{User, UserRepositoriesRequest},
19 17 };
20 use giterated_stack::{AuthenticatedUser, GiteratedStack, StackOperationState};
18 use giterated_stack::{AuthenticatedUser, GiteratedStack, OperationState, StackOperationState};
21 19
22 20 use super::DatabaseBackend;
23 21
@@ -25,7 +23,7 @@ pub async fn user_get_repositories(
25 23 object: User,
26 24 _operation: UserRepositoriesRequest,
27 25 state: DatabaseBackend,
28 _operation_state: StackOperationState,
26 OperationState(_operation_state): OperationState<StackOperationState>,
29 27 requester: Option<AuthenticatedUser>,
30 28 ) -> Result<Vec<RepositorySummary>, OperationError<UserError>> {
31 29 let object = object.clone();
@@ -57,8 +55,8 @@ pub async fn repository_info(
57 55 object: Repository,
58 56 operation: RepositoryInfoRequest,
59 57 state: DatabaseBackend,
60 operation_state: StackOperationState,
61 backend: Arc<GiteratedStack>,
58 OperationState(operation_state): OperationState<StackOperationState>,
59 backend: GiteratedStack,
62 60 requester: Option<AuthenticatedUser>,
63 61 ) -> Result<RepositoryView, OperationError<RepositoryError>> {
64 62 info!("Called");
@@ -118,8 +116,8 @@ pub async fn repository_get_statistics(
118 116 object: Repository,
119 117 operation: RepositoryStatisticsRequest,
120 118 state: DatabaseBackend,
121 operation_state: StackOperationState,
122 backend: Arc<GiteratedStack>,
119 OperationState(operation_state): OperationState<StackOperationState>,
120 backend: GiteratedStack,
123 121 requester: Option<AuthenticatedUser>,
124 122 ) -> Result<RepositoryStatistics, OperationError<RepositoryError>> {
125 123 let object = backend
@@ -147,8 +145,8 @@ pub async fn repository_get_branches(
147 145 object: Repository,
148 146 operation: RepositoryBranchesRequest,
149 147 state: DatabaseBackend,
150 operation_state: StackOperationState,
151 backend: Arc<GiteratedStack>,
148 OperationState(operation_state): OperationState<StackOperationState>,
149 backend: GiteratedStack,
152 150 requester: Option<AuthenticatedUser>,
153 151 ) -> Result<Vec<RepositoryBranch>, OperationError<RepositoryError>> {
154 152 let object = backend
@@ -170,8 +168,8 @@ pub async fn repository_file_from_id(
170 168 object: Repository,
171 169 operation: RepositoryFileFromIdRequest,
172 170 state: DatabaseBackend,
173 operation_state: StackOperationState,
174 backend: Arc<GiteratedStack>,
171 OperationState(operation_state): OperationState<StackOperationState>,
172 backend: GiteratedStack,
175 173
176 174 requester: Option<AuthenticatedUser>,
177 175 ) -> Result<RepositoryFile, OperationError<RepositoryError>> {
@@ -198,8 +196,8 @@ pub async fn repository_file_from_path(
198 196 object: Repository,
199 197 operation: RepositoryFileFromPathRequest,
200 198 state: DatabaseBackend,
201 operation_state: StackOperationState,
202 backend: Arc<GiteratedStack>,
199 OperationState(operation_state): OperationState<StackOperationState>,
200 backend: GiteratedStack,
203 201 requester: Option<AuthenticatedUser>,
204 202 ) -> Result<(RepositoryFile, String), OperationError<RepositoryError>> {
205 203 let object = backend
@@ -228,8 +226,8 @@ pub async fn repository_last_commit_of_file(
228 226 object: Repository,
229 227 operation: RepositoryLastCommitOfFileRequest,
230 228 state: DatabaseBackend,
231 operation_state: StackOperationState,
232 backend: Arc<GiteratedStack>,
229 OperationState(operation_state): OperationState<StackOperationState>,
230 backend: GiteratedStack,
233 231 requester: Option<AuthenticatedUser>,
234 232 ) -> Result<Commit, OperationError<RepositoryError>> {
235 233 let object = backend
@@ -258,8 +256,8 @@ pub async fn repository_commit_by_id(
258 256 object: Repository,
259 257 operation: RepositoryCommitFromIdRequest,
260 258 state: DatabaseBackend,
261 operation_state: StackOperationState,
262 backend: Arc<GiteratedStack>,
259 OperationState(operation_state): OperationState<StackOperationState>,
260 backend: GiteratedStack,
263 261 requester: Option<AuthenticatedUser>,
264 262 ) -> Result<Commit, OperationError<RepositoryError>> {
265 263 let object = backend
@@ -285,8 +283,8 @@ pub async fn repository_diff(
285 283 object: Repository,
286 284 operation: RepositoryDiffRequest,
287 285 state: DatabaseBackend,
288 operation_state: StackOperationState,
289 backend: Arc<GiteratedStack>,
286 OperationState(operation_state): OperationState<StackOperationState>,
287 backend: GiteratedStack,
290 288 requester: Option<AuthenticatedUser>,
291 289 ) -> Result<RepositoryDiff, OperationError<RepositoryError>> {
292 290 let object = backend
@@ -308,8 +306,8 @@ pub async fn repository_diff_patch(
308 306 object: Repository,
309 307 operation: RepositoryDiffPatchRequest,
310 308 state: DatabaseBackend,
311 operation_state: StackOperationState,
312 backend: Arc<GiteratedStack>,
309 OperationState(operation_state): OperationState<StackOperationState>,
310 backend: GiteratedStack,
313 311 requester: Option<AuthenticatedUser>,
314 312 ) -> Result<String, OperationError<RepositoryError>> {
315 313 let object = backend
@@ -331,8 +329,8 @@ pub async fn repository_commit_before(
331 329 object: Repository,
332 330 operation: RepositoryCommitBeforeRequest,
333 331 state: DatabaseBackend,
334 operation_state: StackOperationState,
335 backend: Arc<GiteratedStack>,
332 OperationState(operation_state): OperationState<StackOperationState>,
333 backend: GiteratedStack,
336 334 requester: Option<AuthenticatedUser>,
337 335 ) -> Result<Commit, OperationError<RepositoryError>> {
338 336 let object = backend
@@ -354,7 +352,7 @@ pub async fn instance_authentication_request(
354 352 object: Instance,
355 353 operation: AuthenticationTokenRequest,
356 354 state: DatabaseBackend,
357 _operation_state: StackOperationState,
355 OperationState(_operation_state): OperationState<StackOperationState>,
358 356 // Authorizes the request for SAME-INSTANCE
359 357 // _authorized_instance: AuthorizedInstance,
360 358 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
@@ -370,8 +368,8 @@ pub async fn instance_registration_request(
370 368 _object: Instance,
371 369 operation: RegisterAccountRequest,
372 370 state: DatabaseBackend,
373 _operation_state: StackOperationState, // Authorizes the request for SAME-INSTANCE
374 // _authorized_instance: AuthorizedInstance,
371 OperationState(_operation_state): OperationState<StackOperationState>, // Authorizes the request for SAME-INSTANCE
372 // _authorized_instance: AuthorizedInstance,
375 373 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
376 374 let mut backend = state.user_backend.lock().await;
377 375
@@ -385,7 +383,7 @@ pub async fn instance_create_repository_request(
385 383 _object: Instance,
386 384 operation: RepositoryCreateRequest,
387 385 state: DatabaseBackend,
388 _operation_state: StackOperationState,
386 OperationState(_operation_state): OperationState<StackOperationState>,
389 387 requester: AuthenticatedUser,
390 388 // Authorizes the request for SAME-INSTANCE
391 389 // _authorized_instance: AuthorizedInstance,
@@ -401,7 +399,7 @@ pub async fn instance_create_repository_request(
401 399 pub async fn repository_latest_commit(
402 400 _repository: Repository,
403 401 _state: DatabaseBackend,
404 _operation_state: StackOperationState,
402 OperationState(_operation_state): OperationState<StackOperationState>,
405 403 ) -> Result<LatestCommit, OperationError<RepositoryError>> {
406 404 Ok(LatestCommit(None))
407 405 }

giterated-daemon/src/database_backend/mod.rs

View file
@@ -10,8 +10,8 @@ use giterated_models::instance::Instance;
10 10 use giterated_models::repository::{DefaultBranch, Description, Repository, Visibility};
11 11 use giterated_models::user::{Bio, DisplayName, User};
12 12 use giterated_stack::provider::MetadataProvider;
13 use giterated_stack::SettingMeta;
14 13 use giterated_stack::{AnyObject, AnySetting, GiteratedStack, ObjectMeta, SubstackBuilder};
14 use giterated_stack::{SettingMeta, StackOperationState};
15 15 use serde_json::Value;
16 16 use sqlx::PgPool;
17 17 use std::fmt::Debug;
@@ -36,7 +36,7 @@ pub struct DatabaseBackend {
36 36 pub(self) pool: PgPool,
37 37 pub(self) user_backend: Arc<Mutex<dyn UserBackend + Send>>,
38 38 pub(self) repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>>,
39 pub stack: Arc<OnceCell<Arc<GiteratedStack>>>,
39 pub stack: Arc<OnceCell<GiteratedStack>>,
40 40 }
41 41
42 42 impl DatabaseBackend {
@@ -45,7 +45,7 @@ impl DatabaseBackend {
45 45 user_backend: Arc<Mutex<dyn UserBackend + Send>>,
46 46 repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>>,
47 47 pool: PgPool,
48 stack: Arc<OnceCell<Arc<GiteratedStack>>>,
48 stack: Arc<OnceCell<GiteratedStack>>,
49 49 ) -> Self {
50 50 Self {
51 51 our_instance: instance,
@@ -56,8 +56,8 @@ impl DatabaseBackend {
56 56 }
57 57 }
58 58
59 pub fn into_substack(self) -> SubstackBuilder<Self> {
60 let mut builder = SubstackBuilder::<Self>::new(self.clone());
59 pub fn into_substack(self) -> SubstackBuilder<Self, StackOperationState> {
60 let mut builder = SubstackBuilder::<Self, StackOperationState>::new(self.clone());
61 61
62 62 builder.object_metadata_provider(Box::new(self));
63 63

giterated-daemon/src/main.rs

View file
@@ -11,7 +11,7 @@ use giterated_daemon::{
11 11
12 12 use giterated_models::instance::Instance;
13 13
14 use giterated_stack::GiteratedStack;
14 use giterated_stack::GiteratedStackBuilder;
15 15 use sqlx::{postgres::PgConnectOptions, ConnectOptions, PgPool};
16 16 use std::{net::SocketAddr, str::FromStr, sync::Arc};
17 17 use tokio::{
@@ -92,7 +92,7 @@ async fn main() -> Result<(), Error> {
92 92 stack_cell.clone(),
93 93 );
94 94
95 let mut runtime = GiteratedStack::default();
95 let mut runtime = GiteratedStackBuilder::default();
96 96
97 97 let database_backend = database_backend.into_substack();
98 98 runtime.merge_builder(database_backend);
@@ -100,7 +100,7 @@ async fn main() -> Result<(), Error> {
100 100 let cache_backend = CacheSubstack::default();
101 101 runtime.merge_builder(cache_backend.into_substack());
102 102
103 let runtime = Arc::new(runtime);
103 let runtime = runtime.finish();
104 104
105 105 stack_cell
106 106 .set(runtime.clone())

giterated-models/src/authenticated.rs

View file
@@ -1,152 +1,6 @@
1 use std::{fmt::Debug, sync::Arc};
2
3 use rsa::{
4 pkcs1::DecodeRsaPrivateKey,
5 pss::SigningKey,
6 sha2::Sha256,
7 signature::{RandomizedSigner, SignatureEncoding},
8 RsaPrivateKey,
9 };
10 1 use serde::{Deserialize, Serialize};
11 2
12 use crate::{
13 instance::Instance,
14 message::GiteratedMessage,
15 object::{GiteratedObject, NetworkAnyObject},
16 operation::{GiteratedOperation, NetworkAnyOperation},
17 user::User,
18 };
19
20 #[derive(Debug, Serialize, Deserialize)]
21 pub struct UserTokenMetadata {
22 pub user: User,
23 pub generated_for: Instance,
24 pub exp: u64,
25 }
26
27 #[derive(Debug)]
28 pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
29 pub source: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
30 pub message: GiteratedMessage<O, D>,
31 }
32
33 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
34 pub struct AuthenticatedPayload {
35 pub source: Vec<AuthenticationSource>,
36 pub object: String,
37 pub operation: String,
38 pub payload: Vec<u8>,
39 }
40
41 impl AuthenticatedPayload {
42 pub fn into_message(self) -> GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
43 GiteratedMessage {
44 object: NetworkAnyObject(self.object),
45 operation: self.operation,
46 payload: NetworkAnyOperation(self.payload),
47 }
48 }
49 }
50
51 pub trait AuthenticationSourceProvider: Debug {
52 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
53 }
54
55 pub trait AuthenticationSourceProviders: Debug {
56 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
57 }
58
59 impl<A> AuthenticationSourceProviders for A
60 where
61 A: AuthenticationSourceProvider,
62 {
63 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
64 vec![self.authenticate(payload)]
65 }
66 }
67
68 impl<A, B> AuthenticationSourceProviders for (A, B)
69 where
70 A: AuthenticationSourceProvider,
71 B: AuthenticationSourceProvider,
72 {
73 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
74 let (first, second) = self;
75
76 vec![first.authenticate(payload), second.authenticate(payload)]
77 }
78 }
79
80 impl<O: GiteratedObject, D: GiteratedOperation<O>> Authenticated<O, D> {
81 pub fn new(message: GiteratedMessage<O, D>) -> Self {
82 Self {
83 source: vec![],
84 message,
85 }
86 }
87
88 pub fn append_authentication(
89 &mut self,
90 authentication: Arc<dyn AuthenticationSourceProviders + Send + Sync>,
91 ) {
92 self.source.push(authentication);
93 }
94
95 pub fn into_payload(mut self) -> AuthenticatedPayload {
96 let payload = serde_json::to_vec(&self.message.payload).unwrap();
97
98 AuthenticatedPayload {
99 object: self.message.object.to_string(),
100 operation: self.message.operation,
101 source: self
102 .source
103 .drain(..)
104 .map(|provider| provider.as_ref().authenticate_all(&payload))
105 .flatten()
106 .collect::<Vec<_>>(),
107 payload,
108 }
109 }
110 }
111
112 mod verified {}
113
114 #[derive(Clone, Debug)]
115 pub struct UserAuthenticator {
116 pub user: User,
117 pub token: UserAuthenticationToken,
118 }
119
120 impl AuthenticationSourceProvider for UserAuthenticator {
121 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
122 AuthenticationSource::User {
123 user: self.user.clone(),
124 token: self.token.clone(),
125 }
126 }
127 }
128
129 #[derive(Debug, Clone)]
130 pub struct InstanceAuthenticator {
131 pub instance: Instance,
132 pub private_key: String,
133 }
134
135 impl AuthenticationSourceProvider for InstanceAuthenticator {
136 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
137 let mut rng = rand::thread_rng();
138
139 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
140 let signing_key = SigningKey::<Sha256>::new(private_key);
141 let signature = signing_key.sign_with_rng(&mut rng, payload);
142
143 AuthenticationSource::Instance {
144 instance: self.instance.clone(),
145 // TODO: Actually parse signature from private key
146 signature: InstanceSignature(signature.to_bytes().into_vec()),
147 }
148 }
149 }
3 use crate::{instance::Instance, user::User};
150 4
151 5 #[repr(transparent)]
152 6 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
@@ -179,14 +33,9 @@ impl AsRef<[u8]> for InstanceSignature {
179 33 }
180 34 }
181 35
182 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
183 pub enum AuthenticationSource {
184 User {
185 user: User,
186 token: UserAuthenticationToken,
187 },
188 Instance {
189 instance: Instance,
190 signature: InstanceSignature,
191 },
36 #[derive(Debug, Serialize, Deserialize)]
37 pub struct UserTokenMetadata {
38 pub user: User,
39 pub generated_for: Instance,
40 pub exp: u64,
192 41 }

giterated-protocol/Cargo.toml

View file
@@ -15,4 +15,7 @@ keywords = ["giterated"]
15 15 [dependencies]
16 16 giterated-stack = {path = "../giterated-stack" }
17 17 serde = { version = "1.0.188", features = [ "derive" ]}
18 tracing = "0.1"
18 \ No newline at end of file
18 tracing = "0.1"
19 rand = "0.8"
20 rsa = {version = "0.9", features = ["sha2"]}
21 serde_json = "1.0"
21 \ No newline at end of file

giterated-protocol/src/lib.rs

View file
@@ -1,3 +1,261 @@
1 1 mod substack;
2 2
3 use std::convert::Infallible;
4 use std::fmt::Debug;
5 use std::str::FromStr;
6 use std::{fmt::Display, sync::Arc};
7
8 use giterated_stack::models::{Error, GiteratedObject, GiteratedOperation, Instance, User};
9 use rsa::pkcs1::DecodeRsaPrivateKey;
10 use rsa::pkcs1v15::SigningKey;
11 use rsa::sha2::Sha256;
12 use rsa::signature::{RandomizedSigner, SignatureEncoding};
13 use rsa::RsaPrivateKey;
14 use serde::{Deserialize, Serialize};
3 15 pub use substack::{NetworkedObject, NetworkedOperation, NetworkedSubstack};
16
17 #[derive(Clone, Default)]
18 pub struct NetworkOperationState {
19 authentication: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
20 }
21
22 impl NetworkOperationState {
23 pub fn authenticate(
24 &mut self,
25 provider: impl AuthenticationSourceProviders + Send + Sync + 'static,
26 ) {
27 self.authentication.push(Arc::new(provider))
28 }
29 }
30
31 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
32 pub struct AuthenticatedPayload {
33 pub source: Vec<AuthenticationSource>,
34 pub object: String,
35 pub operation: String,
36 pub payload: Vec<u8>,
37 }
38
39 impl AuthenticatedPayload {
40 pub fn into_message(self) -> GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
41 GiteratedMessage {
42 object: NetworkAnyObject(self.object),
43 operation: self.operation,
44 payload: NetworkAnyOperation(self.payload),
45 }
46 }
47 }
48
49 pub trait AuthenticationSourceProvider: Debug {
50 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
51 }
52
53 pub trait AuthenticationSourceProviders: Debug {
54 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
55 }
56
57 impl<A> AuthenticationSourceProviders for A
58 where
59 A: AuthenticationSourceProvider,
60 {
61 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
62 vec![self.authenticate(payload)]
63 }
64 }
65
66 impl<A, B> AuthenticationSourceProviders for (A, B)
67 where
68 A: AuthenticationSourceProvider,
69 B: AuthenticationSourceProvider,
70 {
71 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
72 let (first, second) = self;
73
74 vec![first.authenticate(payload), second.authenticate(payload)]
75 }
76 }
77
78 mod verified {}
79
80 #[derive(Clone, Debug)]
81 pub struct UserAuthenticator {
82 pub user: User,
83 pub token: UserAuthenticationToken,
84 }
85
86 impl AuthenticationSourceProvider for UserAuthenticator {
87 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
88 AuthenticationSource::User {
89 user: self.user.clone(),
90 token: self.token.clone(),
91 }
92 }
93 }
94
95 #[derive(Debug, Clone)]
96 pub struct InstanceAuthenticator {
97 pub instance: Instance,
98 pub private_key: String,
99 }
100
101 impl AuthenticationSourceProvider for InstanceAuthenticator {
102 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
103 let mut rng = rand::thread_rng();
104
105 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
106 let signing_key = SigningKey::<Sha256>::new(private_key);
107 let signature = signing_key.sign_with_rng(&mut rng, payload);
108
109 AuthenticationSource::Instance {
110 instance: self.instance.clone(),
111 // TODO: Actually parse signature from private key
112 signature: InstanceSignature(signature.to_bytes().into_vec()),
113 }
114 }
115 }
116
117 #[repr(transparent)]
118 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
119 pub struct UserAuthenticationToken(String);
120
121 impl From<String> for UserAuthenticationToken {
122 fn from(value: String) -> Self {
123 Self(value)
124 }
125 }
126
127 impl ToString for UserAuthenticationToken {
128 fn to_string(&self) -> String {
129 self.0.clone()
130 }
131 }
132
133 impl AsRef<str> for UserAuthenticationToken {
134 fn as_ref(&self) -> &str {
135 &self.0
136 }
137 }
138
139 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
140 pub struct InstanceSignature(Vec<u8>);
141
142 impl AsRef<[u8]> for InstanceSignature {
143 fn as_ref(&self) -> &[u8] {
144 &self.0
145 }
146 }
147
148 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
149 pub enum AuthenticationSource {
150 User {
151 user: User,
152 token: UserAuthenticationToken,
153 },
154 Instance {
155 instance: Instance,
156 signature: InstanceSignature,
157 },
158 }
159
160 #[derive(Serialize)]
161 #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation<O>"))]
162 pub struct GiteratedMessage<O: GiteratedObject, V: GiteratedOperation<O>> {
163 #[serde(with = "string")]
164 pub object: O,
165 pub operation: String,
166 pub payload: V,
167 }
168
169 #[allow(unused)]
170 mod string {
171 use std::fmt::Display;
172 use std::str::FromStr;
173
174 use serde::{de, Deserialize, Deserializer, Serializer};
175
176 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
177 where
178 T: Display,
179 S: Serializer,
180 {
181 serializer.collect_str(value)
182 }
183
184 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
185 where
186 T: FromStr,
187 T::Err: Display,
188 D: Deserializer<'de>,
189 {
190 String::deserialize(deserializer)?
191 .parse()
192 .map_err(de::Error::custom)
193 }
194 }
195
196 impl GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
197 pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
198 &self,
199 ) -> Result<GiteratedMessage<O, V>, ()> {
200 let object = O::from_object_str(&self.object.0).map_err(|_| ())?;
201 let payload = serde_json::from_slice::<V>(&self.payload.0).map_err(|_| ())?;
202
203 Ok(GiteratedMessage {
204 object,
205 operation: self.operation.clone(),
206 payload,
207 })
208 }
209 }
210
211 impl<V: GiteratedOperation<O> + Debug, O: GiteratedObject + Debug> Debug
212 for GiteratedMessage<O, V>
213 {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 f.debug_struct("GiteratedMessage")
216 .field("object", &self.object)
217 .field("operation", &self.operation)
218 .field("payload", &self.payload)
219 .finish()
220 }
221 }
222
223 #[derive(Clone, Debug, Serialize, Deserialize)]
224 #[serde(transparent)]
225 #[repr(transparent)]
226 pub struct NetworkAnyObject(pub String);
227
228 impl GiteratedObject for NetworkAnyObject {
229 fn object_name() -> &'static str {
230 "any"
231 }
232
233 fn from_object_str(object_str: &str) -> Result<Self, Error> {
234 Ok(Self(object_str.to_string()))
235 }
236 }
237
238 impl Display for NetworkAnyObject {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 f.write_str(&self.0)
241 }
242 }
243
244 impl FromStr for NetworkAnyObject {
245 type Err = Infallible;
246
247 fn from_str(s: &str) -> Result<Self, Self::Err> {
248 Ok(Self(s.to_owned()))
249 }
250 }
251
252 #[derive(Clone, Debug, Serialize, Deserialize)]
253 #[serde(transparent)]
254 #[repr(transparent)]
255 pub struct NetworkAnyOperation(pub Vec<u8>);
256
257 impl<O: GiteratedObject> GiteratedOperation<O> for NetworkAnyOperation {
258 type Success = Vec<u8>;
259
260 type Failure = Vec<u8>;
261 }

giterated-protocol/src/substack.rs

View file
@@ -2,12 +2,14 @@ use std::{fmt::Display, str::FromStr, sync::Arc};
2 2
3 3 use giterated_stack::{
4 4 models::{Error, GiteratedObject, GiteratedOperation, IntoInternalError, OperationError},
5 AnyFailure, AnyObject, AnyOperation, AnySuccess, GiteratedStack, ObjectOperationPair,
6 StackOperationState, SubstackBuilder,
5 AnyFailure, AnyObject, AnyOperation, AnySuccess, GiteratedStack, GiteratedStackInner,
6 ObjectOperationPair, OperationState, StackOperationState, SubstackBuilder,
7 7 };
8 8 use serde::{Deserialize, Serialize};
9 9 use tracing::{trace, warn};
10 10
11 use crate::NetworkOperationState;
12
11 13 /// A Giterated substack that attempts to resolve with a remote, networked Giterated Daemon.
12 14 ///
13 15 /// # Usage
@@ -54,15 +56,24 @@ pub struct NetworkedSubstack {
54 56
55 57 impl Default for NetworkedSubstack {
56 58 fn default() -> Self {
57 todo!()
59 Self { home_uri: None }
58 60 }
59 61 }
60 62
61 63 impl NetworkedSubstack {
62 pub fn into_substack(self) -> SubstackBuilder<Self> {
64 pub fn into_server_substack(self) -> SubstackBuilder<Self, StackOperationState> {
63 65 let mut stack = SubstackBuilder::new(self);
64 66
65 stack.operation(handle_network_operation);
67 stack.operation(handle_network_operation::<StackOperationState>);
68
69 // TODO: optional
70 stack.dynamic_operation(try_handle_with_remote);
71
72 stack
73 }
74
75 pub fn into_client_substack(self) -> SubstackBuilder<Self, NetworkOperationState> {
76 let mut stack = SubstackBuilder::new(self);
66 77
67 78 // TODO: optional
68 79 stack.dynamic_operation(try_handle_with_remote);
@@ -71,17 +82,17 @@ impl NetworkedSubstack {
71 82 }
72 83 }
73 84
74 pub async fn handle_network_operation(
85 pub async fn handle_network_operation<OS: Send + Sync + Clone + 'static>(
75 86 object: NetworkedObject,
76 87 operation: NetworkedOperation,
77 88 _state: NetworkedSubstack,
78 operation_state: StackOperationState,
79 stack: Arc<GiteratedStack>,
89 OperationState(operation_state): OperationState<OS>,
90 stack: GiteratedStack<OS>,
80 91 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
81 92 trace!("Handle network operation");
82 93 let mut result = None;
83 94
84 for (_, object_meta) in &stack.metadata.objects {
95 for (_, object_meta) in &stack.inner.metadata.objects {
85 96 if let Ok(object) = (object_meta.from_str)(&object.0) {
86 97 // TODO: This is definitely going to resolve us
87 98 result = Some((object, object_meta));
@@ -97,6 +108,7 @@ pub async fn handle_network_operation(
97 108 );
98 109
99 110 let operation_meta = stack
111 .inner
100 112 .metadata
101 113 .operations
102 114 .get(&ObjectOperationPair {
@@ -204,7 +216,7 @@ pub async fn try_handle_with_remote(
204 216 operation: AnyOperation,
205 217 state: NetworkedSubstack,
206 218 _operation_state: StackOperationState,
207 stack: Arc<GiteratedStack>,
219 stack: Arc<GiteratedStackInner>,
208 220 ) -> Result<AnySuccess, OperationError<AnyFailure>> {
209 221 trace!(
210 222 "Try handling object operation {}::{} with remote",

giterated-stack/src/dynamic.rs

View file
@@ -0,0 +1,220 @@
1 use std::{any::Any, ops::Deref, sync::Arc};
2
3 use giterated_models::{
4 object::GiteratedObject, operation::GiteratedOperation, settings::Setting,
5 value::GiteratedObjectValue,
6 };
7
8 use crate::{ObjectOperationPair, ObjectSettingPair, ObjectValuePair, ValueMeta};
9
10 #[derive(Clone)]
11 pub struct AnyObject {
12 inner: Arc<dyn Any + Send + Sync>,
13 kind: &'static str,
14 }
15
16 impl AnyObject {
17 pub fn new<O: GiteratedObject + 'static>(object: O) -> Self {
18 Self {
19 inner: Arc::new(object) as _,
20 kind: O::object_name(),
21 }
22 }
23
24 pub fn new_raw(_object: Arc<dyn Any + Send + Sync>, _kind: &'static str) -> Self {
25 todo!()
26 }
27
28 pub fn kind(&self) -> &'static str {
29 self.kind
30 }
31 }
32
33 impl Deref for AnyObject {
34 type Target = dyn Any + Send + Sync;
35
36 fn deref(&self) -> &Self::Target {
37 self.inner.as_ref()
38 }
39 }
40
41 #[derive(Clone)]
42 pub struct AnyOperation {
43 inner: Arc<dyn Any + Send + Sync>,
44 kind: ObjectOperationPair<'static>,
45 }
46
47 impl AnyOperation {
48 pub fn new<O: GiteratedObject, D: GiteratedOperation<O> + 'static>(operation: D) -> Self {
49 Self {
50 inner: Arc::new(operation) as _,
51 kind: ObjectOperationPair::from_types::<O, D>(),
52 }
53 }
54
55 pub fn new_raw(
56 _operation: Arc<dyn Any + Send + Sync>,
57 _kind: ObjectOperationPair<'static>,
58 ) -> Self {
59 todo!()
60 }
61
62 pub fn kind(&self) -> ObjectOperationPair<'static> {
63 self.kind
64 }
65 }
66
67 impl Deref for AnyOperation {
68 type Target = dyn Any + Send + Sync;
69
70 fn deref(&self) -> &Self::Target {
71 self.inner.as_ref()
72 }
73 }
74
75 #[derive(Clone)]
76 pub struct AnyValue {
77 inner: Arc<dyn Any + Send + Sync>,
78 kind: ObjectValuePair<'static>,
79 }
80
81 impl AnyValue {
82 pub fn new<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static>(
83 value: V,
84 ) -> Self {
85 Self {
86 inner: Arc::new(value) as _,
87 kind: ObjectValuePair::from_types::<O, V>(),
88 }
89 }
90
91 pub fn new_raw(_value: Arc<dyn Any + Send + Sync>, _kind: ObjectValuePair<'static>) -> Self {
92 todo!()
93 }
94
95 pub fn kind(&self) -> ObjectValuePair<'static> {
96 self.kind
97 }
98 }
99
100 impl Deref for AnyValue {
101 type Target = dyn Any + Send + Sync;
102
103 fn deref(&self) -> &Self::Target {
104 self.inner.as_ref()
105 }
106 }
107
108 #[derive(Clone)]
109 pub struct AnySetting {
110 inner: Arc<dyn Any + Send + Sync>,
111 kind: ObjectSettingPair<'static>,
112 }
113
114 impl AnySetting {
115 pub fn new<O: GiteratedObject, S: Setting + 'static>(setting: S) -> Self {
116 Self {
117 inner: Arc::new(setting) as _,
118 kind: ObjectSettingPair::from_types::<O, S>(),
119 }
120 }
121
122 pub fn new_raw(
123 _setting: Arc<dyn Any + Send + Sync>,
124 _kind: ObjectSettingPair<'static>,
125 ) -> Self {
126 todo!()
127 }
128
129 pub fn kind(&self) -> ObjectSettingPair<'static> {
130 self.kind
131 }
132 }
133
134 impl Deref for AnySetting {
135 type Target = dyn Any + Send + Sync;
136
137 fn deref(&self) -> &Self::Target {
138 self.inner.as_ref()
139 }
140 }
141
142 #[derive(Clone)]
143 pub struct AnySuccess(pub Arc<dyn Any + Send>);
144
145 #[derive(Clone)]
146 pub struct AnyFailure(pub Arc<dyn Any + Send>);
147
148 /// Should be renamed.
149 ///
150 /// Allows accepting object types that are either GiteratedObject types or
151 /// AnyObject.
152 pub trait MaybeDynamicObject: Clone {
153 fn from_any(object: &AnyObject) -> Self;
154
155 fn object_name() -> &'static str;
156 }
157
158 impl<O: GiteratedObject> MaybeDynamicObject for O {
159 fn from_any(_object: &AnyObject) -> Self {
160 todo!()
161 }
162
163 fn object_name() -> &'static str {
164 <O as GiteratedObject>::object_name()
165 }
166 }
167
168 impl MaybeDynamicObject for AnyObject {
169 fn from_any(object: &AnyObject) -> Self {
170 object.clone()
171 }
172
173 fn object_name() -> &'static str {
174 "any"
175 }
176 }
177
178 pub trait MaybeDynamicValue {
179 fn from_any(value: &AnyValue) -> Self;
180 fn into_any(self) -> AnyValue;
181 fn meta() -> Option<ValueMeta>;
182
183 fn value_name() -> &'static str;
184 }
185
186 impl<V: GiteratedObjectValue> MaybeDynamicValue for V {
187 fn from_any(_object: &AnyValue) -> Self {
188 todo!()
189 }
190
191 fn value_name() -> &'static str {
192 todo!()
193 }
194
195 fn into_any(self) -> AnyValue {
196 todo!()
197 }
198
199 fn meta() -> Option<ValueMeta> {
200 todo!()
201 }
202 }
203
204 impl MaybeDynamicValue for AnyValue {
205 fn value_name() -> &'static str {
206 "any"
207 }
208
209 fn from_any(value: &AnyValue) -> Self {
210 value.clone()
211 }
212
213 fn into_any(self) -> AnyValue {
214 self
215 }
216
217 fn meta() -> Option<ValueMeta> {
218 todo!()
219 }
220 }

giterated-stack/src/handler/handler_impl.rs

View file
@@ -7,7 +7,7 @@ use crate::{HandlerResolvable, IntoGiteratedHandler};
7 7 impl<R1, S, OS, Success, Failure, H, Fut>
8 8 IntoGiteratedHandler<(R1,), (), S, OS, Result<Success, OperationError<Failure>>> for H
9 9 where
10 H: FnMut(R1, S, OS) -> Fut + Clone,
10 H: FnMut(R1, S) -> Fut + Clone,
11 11 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
12 12 Success: 'static,
13 13 Failure: 'static,
@@ -21,10 +21,10 @@ where
21 21 &self,
22 22 parameters: (R1,),
23 23 state: S,
24 operation_state: OS,
24 _operation_state: OS,
25 25 ) -> Result<Success, OperationError<Failure>> {
26 26 let (r1,) = parameters;
27 (self.clone())(r1, state, operation_state).await
27 (self.clone())(r1, state).await
28 28 }
29 29 }
30 30
@@ -32,7 +32,7 @@ where
32 32 impl<R1, A1, S, OS, Success, Failure, H, Fut>
33 33 IntoGiteratedHandler<(R1,), (A1,), S, OS, Result<Success, OperationError<Failure>>> for H
34 34 where
35 H: FnMut(R1, S, OS, A1) -> Fut + Clone,
35 H: FnMut(R1, S, A1) -> Fut + Clone,
36 36 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
37 37 Success: 'static,
38 38 Failure: 'static,
@@ -54,7 +54,7 @@ where
54 54 .await
55 55 .map_err(|e| OperationError::Internal(e.into()))?;
56 56 let (r1,) = parameters;
57 (self.clone())(r1, state, operation_state, a1).await
57 (self.clone())(r1, state, a1).await
58 58 }
59 59 }
60 60
@@ -62,7 +62,7 @@ where
62 62 impl<R1, A1, A2, S, OS, Success, Failure, H, Fut>
63 63 IntoGiteratedHandler<(R1,), (A1, A2), S, OS, Result<Success, OperationError<Failure>>> for H
64 64 where
65 H: FnMut(R1, S, OS, A1, A2) -> Fut + Clone,
65 H: FnMut(R1, S, A1, A2) -> Fut + Clone,
66 66 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
67 67 Success: 'static,
68 68 Failure: 'static,
@@ -89,7 +89,7 @@ where
89 89 .await
90 90 .map_err(|e| OperationError::Internal(e.into()))?;
91 91 let (r1,) = parameters;
92 (self.clone())(r1, state, operation_state, a1, a2).await
92 (self.clone())(r1, state, a1, a2).await
93 93 }
94 94 }
95 95
@@ -97,7 +97,7 @@ where
97 97 impl<R1, A1, A2, A3, S, OS, Success, Failure, H, Fut>
98 98 IntoGiteratedHandler<(R1,), (A1, A2, A3), S, OS, Result<Success, OperationError<Failure>>> for H
99 99 where
100 H: FnMut(R1, S, OS, A1, A2, A3) -> Fut + Clone,
100 H: FnMut(R1, S, A1, A2, A3) -> Fut + Clone,
101 101 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
102 102 Success: 'static,
103 103 Failure: 'static,
@@ -129,7 +129,7 @@ where
129 129 .await
130 130 .map_err(|e| OperationError::Internal(e.into()))?;
131 131 let (r1,) = parameters;
132 (self.clone())(r1, state, operation_state, a1, a2, a3).await
132 (self.clone())(r1, state, a1, a2, a3).await
133 133 }
134 134 }
135 135
@@ -137,7 +137,7 @@ where
137 137 impl<R1, R2, S, OS, Success, Failure, H, Fut>
138 138 IntoGiteratedHandler<(R1, R2), (), S, OS, Result<Success, OperationError<Failure>>> for H
139 139 where
140 H: FnMut(R1, R2, S, OS) -> Fut + Clone,
140 H: FnMut(R1, R2, S) -> Fut + Clone,
141 141 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
142 142 Success: 'static,
143 143 Failure: 'static,
@@ -152,10 +152,10 @@ where
152 152 &self,
153 153 parameters: (R1, R2),
154 154 state: S,
155 operation_state: OS,
155 _operation_state: OS,
156 156 ) -> Result<Success, OperationError<Failure>> {
157 157 let (r1, r2) = parameters;
158 (self.clone())(r1, r2, state, operation_state).await
158 (self.clone())(r1, r2, state).await
159 159 }
160 160 }
161 161
@@ -163,7 +163,7 @@ where
163 163 impl<R1, R2, A1, S, OS, Success, Failure, H, Fut>
164 164 IntoGiteratedHandler<(R1, R2), (A1,), S, OS, Result<Success, OperationError<Failure>>> for H
165 165 where
166 H: FnMut(R1, R2, S, OS, A1) -> Fut + Clone,
166 H: FnMut(R1, R2, S, A1) -> Fut + Clone,
167 167 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
168 168 Success: 'static,
169 169 Failure: 'static,
@@ -187,7 +187,7 @@ where
187 187 .map_err(|e| OperationError::Internal(e.into()))?;
188 188
189 189 let (r1, r2) = parameters;
190 (self.clone())(r1, r2, state, operation_state, a1).await
190 (self.clone())(r1, r2, state, a1).await
191 191 }
192 192 }
193 193
@@ -195,7 +195,7 @@ where
195 195 impl<R1, R2, A1, A2, S, OS, Success, Failure, H, Fut>
196 196 IntoGiteratedHandler<(R1, R2), (A1, A2), S, OS, Result<Success, OperationError<Failure>>> for H
197 197 where
198 H: FnMut(R1, R2, S, OS, A1, A2) -> Fut + Clone,
198 H: FnMut(R1, R2, S, A1, A2) -> Fut + Clone,
199 199 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
200 200 Success: 'static,
201 201 Failure: 'static,
@@ -224,7 +224,7 @@ where
224 224 .map_err(|e| OperationError::Internal(e.into()))?;
225 225
226 226 let (r1, r2) = parameters;
227 (self.clone())(r1, r2, state, operation_state, a1, a2).await
227 (self.clone())(r1, r2, state, a1, a2).await
228 228 }
229 229 }
230 230
@@ -233,7 +233,7 @@ impl<R1, R2, A1, A2, A3, S, OS, Success, Failure, H, Fut>
233 233 IntoGiteratedHandler<(R1, R2), (A1, A2, A3), S, OS, Result<Success, OperationError<Failure>>>
234 234 for H
235 235 where
236 H: FnMut(R1, R2, S, OS, A1, A2, A3) -> Fut + Clone,
236 H: FnMut(R1, R2, S, A1, A2, A3) -> Fut + Clone,
237 237 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
238 238 Success: 'static,
239 239 Failure: 'static,
@@ -267,6 +267,6 @@ where
267 267 .map_err(|e| OperationError::Internal(e.into()))?;
268 268
269 269 let (r1, r2) = parameters;
270 (self.clone())(r1, r2, state, operation_state, a1, a2, a3).await
270 (self.clone())(r1, r2, state, a1, a2, a3).await
271 271 }
272 272 }

giterated-stack/src/handler/mod.rs

View file
@@ -30,18 +30,17 @@ impl<Kind> Default for HandlerTree<Kind> {
30 30 }
31 31 }
32 32
33 impl<'fut: 'o + 'p, 'p, 'o, P, O, E> HandlerTree<HandlerWrapper<P, O, E>>
33 impl<'fut: 'o + 'p, 'p, 'o, P, O, E, OS> HandlerTree<HandlerWrapper<P, O, E, OS>>
34 34 where
35 35 P: Clone,
36 36 {
37 pub fn push(&mut self, handler: HandlerWrapper<P, O, E>) {
37 pub fn push(&mut self, handler: HandlerWrapper<P, O, E, OS>) {
38 38 self.elements.push(handler);
39 39 }
40 pub async fn handle(
41 &self,
42 parameters: P,
43 operation_state: StackOperationState,
44 ) -> Result<O, OperationError<E>> {
40 pub async fn handle(&self, parameters: P, operation_state: OS) -> Result<O, OperationError<E>>
41 where
42 OS: Clone + 'static,
43 {
45 44 for handler in self.elements.iter() {
46 45 match handler
47 46 .handle(parameters.clone(), operation_state.clone())
@@ -60,12 +59,12 @@ where
60 59 }
61 60 }
62 61
63 pub struct HandlerWrapper<P, O, E> {
62 pub struct HandlerWrapper<P, O, E, OS> {
64 63 func: Arc<
65 64 dyn Fn(
66 65 P,
67 66 Arc<dyn Any + Send + Sync>,
68 StackOperationState,
67 OS,
69 68 ) -> LocalBoxFuture<'static, Result<O, OperationError<E>>>
70 69 + Send
71 70 + Sync,
@@ -73,17 +72,16 @@ pub struct HandlerWrapper<P, O, E> {
73 72 state: Arc<dyn Any + Send + Sync>,
74 73 }
75 74
76 impl<P, O, E> HandlerWrapper<P, O, E> {
75 impl<P, O, E, OS: 'static> HandlerWrapper<P, O, E, OS> {
77 76 pub fn new<S, F, A>(state: S, handler: F) -> Self
78 77 where
79 F: IntoGiteratedHandler<P, A, S, StackOperationState, Result<O, OperationError<E>>>
80 + Send
81 + Sync,
78 F: IntoGiteratedHandler<P, A, S, OS, Result<O, OperationError<E>>> + Send + Sync,
82 79 S: Send + Sync + Clone + 'static,
83 80 E: 'static,
84 81 P: 'static + Clone,
85 82 F: 'static,
86 83 O: 'static,
84 OS: Clone,
87 85 {
88 86 let state = Arc::new(state);
89 87
@@ -91,9 +89,7 @@ impl<P, O, E> HandlerWrapper<P, O, E> {
91 89 let state_two = state.clone();
92 90 HandlerWrapper {
93 91 func: Arc::new(
94 move |args: P,
95 state: Arc<dyn Any + Send + Sync>,
96 operation_state: StackOperationState| {
92 move |args: P, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
97 93 let handler = handler_func.clone();
98 94 let operation_state = operation_state.clone();
99 95 let state = state.downcast_ref::<S>().unwrap();
@@ -110,17 +106,13 @@ impl<P, O, E> HandlerWrapper<P, O, E> {
110 106 }
111 107 }
112 108
113 pub async fn handle(
114 &self,
115 required: P,
116 operation_state: StackOperationState,
117 ) -> Result<O, OperationError<E>> {
109 pub async fn handle(&self, required: P, operation_state: OS) -> Result<O, OperationError<E>> {
118 110 (self.func)(required, self.state.clone(), operation_state).await
119 111 }
120 112
121 pub fn map<F, N, R>(self, predicate: F) -> HandlerWrapper<N, O, R>
113 pub fn map<F, N, R>(self, predicate: F) -> HandlerWrapper<N, O, R, OS>
122 114 where
123 F: Fn(&N, &StackOperationState) -> Result<P, OperationError<R>> + Clone + Send + Sync,
115 F: Fn(&N, &OS) -> Result<P, OperationError<R>> + Clone + Send + Sync,
124 116 R: std::fmt::Debug + 'static,
125 117 E: Into<OperationError<R>> + 'static,
126 118 OperationError<R>: From<OperationError<E>> + 'static,
@@ -128,17 +120,16 @@ impl<P, O, E> HandlerWrapper<P, O, E> {
128 120 N: 'static,
129 121 P: 'static,
130 122 O: 'static,
123 OS: Clone,
131 124 {
132 125 let func = Arc::new(self.func);
133 126 let predicate = Arc::new(predicate);
134 127 HandlerWrapper {
135 128 func: Arc::new(
136 move |args: N,
137 state: Arc<dyn Any + Send + Sync>,
138 operation_state: StackOperationState| {
129 move |args: N, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
139 130 let predicate_output = predicate(&args, &operation_state);
140 131 let func = func.clone();
141 let operation_state: StackOperationState = operation_state.clone();
132 let operation_state: OS = operation_state.clone();
142 133 async move {
143 134 let predicate_output = predicate_output?;
144 135 let operation_state = operation_state;
@@ -154,9 +145,9 @@ impl<P, O, E> HandlerWrapper<P, O, E> {
154 145 }
155 146 }
156 147
157 pub fn map_return<F, NR, NE>(self, predicate: F) -> HandlerWrapper<P, NR, NE>
148 pub fn map_return<F, NR, NE>(self, predicate: F) -> HandlerWrapper<P, NR, NE, OS>
158 149 where
159 F: Fn(Result<O, OperationError<E>>, &StackOperationState) -> Result<NR, OperationError<NE>>
150 F: Fn(Result<O, OperationError<E>>, &OS) -> Result<NR, OperationError<NE>>
160 151 + Clone
161 152 + Send
162 153 + Sync,
@@ -164,14 +155,13 @@ impl<P, O, E> HandlerWrapper<P, O, E> {
164 155 F: 'static,
165 156 E: 'static,
166 157 P: 'static,
158 OS: Clone,
167 159 {
168 160 let predicate = Arc::new(predicate);
169 161 let func = self.func;
170 162 HandlerWrapper {
171 163 func: Arc::new(
172 move |args: P,
173 state: Arc<dyn Any + Send + Sync>,
174 operation_state: StackOperationState| {
164 move |args: P, state: Arc<dyn Any + Send + Sync>, operation_state: OS| {
175 165 let clone = predicate.clone();
176 166 let func = func.clone();
177 167 let _statoperation_statee = operation_state.clone();
@@ -204,7 +194,7 @@ pub trait HandlerResolvable<RequiredParameters, OperationState>: Sized {
204 194 }
205 195
206 196 #[async_trait::async_trait(?Send)]
207 impl<R> HandlerResolvable<R, StackOperationState> for Arc<GiteratedStack> {
197 impl<R> HandlerResolvable<R, StackOperationState> for GiteratedStack<StackOperationState> {
208 198 type Error = MissingValue;
209 199
210 200 async fn from_handler_state(

giterated-stack/src/lib.rs

View file
@@ -1,4 +1,6 @@
1 mod dynamic;
1 2 mod handler;
3 pub use dynamic::*;
2 4 pub use handler::*;
3 5 mod meta;
4 6 pub use meta::*;
@@ -9,18 +11,19 @@ mod substack;
9 11 use serde::{de::DeserializeOwned, Deserialize, Serialize};
10 12 pub use stack::*;
11 13 pub use substack::*;
12 pub mod state;
13 14 pub mod update;
14 15
15 16 // Temp pub use to figure out what's important
16 17 pub mod models {
17 18 pub use anyhow::Error;
18 19 pub use giterated_models::error::{IntoInternalError, OperationError};
20 pub use giterated_models::instance::Instance;
19 21 pub use giterated_models::object::GiteratedObject;
20 22 pub use giterated_models::operation::GiteratedOperation;
23 pub use giterated_models::user::User;
21 24 }
22 25
23 use std::{any::Any, convert::Infallible, ops::Deref, sync::Arc};
26 use std::{convert::Infallible, ops::Deref};
24 27
25 28 use core::fmt::Debug;
26 29 use giterated_models::{
@@ -405,7 +408,7 @@ impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance
405 408 #[derive(Clone)]
406 409 pub struct StackOperationState {
407 410 pub our_instance: Instance,
408 pub runtime: Arc<GiteratedStack>,
411 pub runtime: GiteratedStack<StackOperationState>,
409 412 pub instance: Option<AuthenticatedInstance>,
410 413 pub user: Option<AuthenticatedUser>,
411 414 }
@@ -459,214 +462,16 @@ where
459 462 type Failure = ();
460 463 }
461 464
462 #[derive(Clone)]
463 pub struct AnyObject {
464 inner: Arc<dyn Any + Send + Sync>,
465 kind: &'static str,
466 }
467
468 impl AnyObject {
469 pub fn new<O: GiteratedObject + 'static>(object: O) -> Self {
470 Self {
471 inner: Arc::new(object) as _,
472 kind: O::object_name(),
473 }
474 }
475
476 pub fn new_raw(_object: Arc<dyn Any + Send + Sync>, _kind: &'static str) -> Self {
477 todo!()
478 }
479
480 pub fn kind(&self) -> &'static str {
481 self.kind
482 }
483 }
484
485 impl Deref for AnyObject {
486 type Target = dyn Any + Send + Sync;
487
488 fn deref(&self) -> &Self::Target {
489 self.inner.as_ref()
490 }
491 }
492
493 #[derive(Clone)]
494 pub struct AnyOperation {
495 inner: Arc<dyn Any + Send + Sync>,
496 kind: ObjectOperationPair<'static>,
497 }
498
499 impl AnyOperation {
500 pub fn new<O: GiteratedObject, D: GiteratedOperation<O> + 'static>(operation: D) -> Self {
501 Self {
502 inner: Arc::new(operation) as _,
503 kind: ObjectOperationPair::from_types::<O, D>(),
504 }
505 }
506
507 pub fn new_raw(
508 _operation: Arc<dyn Any + Send + Sync>,
509 _kind: ObjectOperationPair<'static>,
510 ) -> Self {
511 todo!()
512 }
513
514 pub fn kind(&self) -> ObjectOperationPair<'static> {
515 self.kind
516 }
517 }
518
519 impl Deref for AnyOperation {
520 type Target = dyn Any + Send + Sync;
521
522 fn deref(&self) -> &Self::Target {
523 self.inner.as_ref()
524 }
525 }
526
527 #[derive(Clone)]
528 pub struct AnyValue {
529 inner: Arc<dyn Any + Send + Sync>,
530 kind: ObjectValuePair<'static>,
531 }
532
533 impl AnyValue {
534 pub fn new<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static>(
535 value: V,
536 ) -> Self {
537 Self {
538 inner: Arc::new(value) as _,
539 kind: ObjectValuePair::from_types::<O, V>(),
540 }
541 }
542
543 pub fn new_raw(_value: Arc<dyn Any + Send + Sync>, _kind: ObjectValuePair<'static>) -> Self {
544 todo!()
545 }
546
547 pub fn kind(&self) -> ObjectValuePair<'static> {
548 self.kind
549 }
550 }
551
552 impl Deref for AnyValue {
553 type Target = dyn Any + Send + Sync;
554
555 fn deref(&self) -> &Self::Target {
556 self.inner.as_ref()
557 }
558 }
559
560 #[derive(Clone)]
561 pub struct AnySetting {
562 inner: Arc<dyn Any + Send + Sync>,
563 kind: ObjectSettingPair<'static>,
564 }
465 pub struct OperationState<OS>(pub OS);
565 466
566 impl AnySetting {
567 pub fn new<O: GiteratedObject, S: Setting + 'static>(setting: S) -> Self {
568 Self {
569 inner: Arc::new(setting) as _,
570 kind: ObjectSettingPair::from_types::<O, S>(),
571 }
572 }
573
574 pub fn new_raw(
575 _setting: Arc<dyn Any + Send + Sync>,
576 _kind: ObjectSettingPair<'static>,
577 ) -> Self {
578 todo!()
579 }
580
581 pub fn kind(&self) -> ObjectSettingPair<'static> {
582 self.kind
583 }
584 }
585
586 impl Deref for AnySetting {
587 type Target = dyn Any + Send + Sync;
588
589 fn deref(&self) -> &Self::Target {
590 self.inner.as_ref()
591 }
592 }
593
594 #[derive(Clone)]
595 pub struct AnySuccess(pub Arc<dyn Any + Send>);
596
597 #[derive(Clone)]
598 pub struct AnyFailure(pub Arc<dyn Any + Send>);
599
600 /// Should be renamed.
601 ///
602 /// Allows accepting object types that are either GiteratedObject types or
603 /// AnyObject.
604 pub trait MaybeDynamicObject: Clone {
605 fn from_any(object: &AnyObject) -> Self;
606
607 fn object_name() -> &'static str;
608 }
609
610 impl<O: GiteratedObject> MaybeDynamicObject for O {
611 fn from_any(_object: &AnyObject) -> Self {
612 todo!()
613 }
614
615 fn object_name() -> &'static str {
616 <O as GiteratedObject>::object_name()
617 }
618 }
619
620 impl MaybeDynamicObject for AnyObject {
621 fn from_any(object: &AnyObject) -> Self {
622 object.clone()
623 }
624
625 fn object_name() -> &'static str {
626 "any"
627 }
628 }
629
630 pub trait MaybeDynamicValue {
631 fn from_any(value: &AnyValue) -> Self;
632 fn into_any(self) -> AnyValue;
633 fn meta() -> Option<ValueMeta>;
634
635 fn value_name() -> &'static str;
636 }
637
638 impl<V: GiteratedObjectValue> MaybeDynamicValue for V {
639 fn from_any(_object: &AnyValue) -> Self {
640 todo!()
641 }
642
643 fn value_name() -> &'static str {
644 todo!()
645 }
646
647 fn into_any(self) -> AnyValue {
648 todo!()
649 }
650
651 fn meta() -> Option<ValueMeta> {
652 todo!()
653 }
654 }
655
656 impl MaybeDynamicValue for AnyValue {
657 fn value_name() -> &'static str {
658 "any"
659 }
660
661 fn from_any(value: &AnyValue) -> Self {
662 value.clone()
663 }
664
665 fn into_any(self) -> AnyValue {
666 self
667 }
467 #[async_trait::async_trait(?Send)]
468 impl<P, OS> HandlerResolvable<P, OS> for OperationState<OS> {
469 type Error = MissingValue;
668 470
669 fn meta() -> Option<ValueMeta> {
471 async fn from_handler_state(
472 _required_parameters: &P,
473 _operation_state: &OS,
474 ) -> Result<Self, Self::Error> {
670 475 todo!()
671 476 }
672 477 }

giterated-stack/src/meta/mod.rs

View file
@@ -1,4 +1,4 @@
1 use std::{any::Any, collections::HashMap, str::FromStr, sync::Arc};
1 use std::{any::Any, collections::HashMap, str::FromStr};
2 2
3 3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 4 use giterated_models::{
@@ -288,7 +288,7 @@ pub struct SettingMeta {
288 288 pub setting_updated: for<'fut> fn(
289 289 AnyObject,
290 290 AnySetting,
291 Arc<GiteratedStack>,
291 GiteratedStack<StackOperationState>,
292 292 &StackOperationState,
293 293 ) -> LocalBoxFuture<'_, ()>,
294 294 }
@@ -300,7 +300,7 @@ pub trait IntoSettingMeta<O> {
300 300 fn setting_updated(
301 301 object: AnyObject,
302 302 setting: AnySetting,
303 stack: Arc<GiteratedStack>,
303 stack: GiteratedStack<StackOperationState>,
304 304 operation_state: &StackOperationState,
305 305 ) -> LocalBoxFuture<'_, ()>;
306 306 }
@@ -321,7 +321,7 @@ impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta
321 321 fn setting_updated(
322 322 object: AnyObject,
323 323 setting: AnySetting,
324 stack: Arc<GiteratedStack>,
324 stack: GiteratedStack<StackOperationState>,
325 325 operation_state: &StackOperationState,
326 326 ) -> LocalBoxFuture<'_, ()> {
327 327 async move {

giterated-stack/src/stack.rs

View file
@@ -1,15 +1,12 @@
1 1 use std::any::Any;
2 2
3 3 use std::fmt::Debug;
4 use std::marker::PhantomData;
4 5 use std::ops::Deref;
5 6 use std::{collections::HashMap, sync::Arc};
6 7
7 use giterated_models::authenticated::AuthenticatedPayload;
8 use giterated_models::error::{GetValueError, IntoInternalError};
9 use giterated_models::message::GiteratedMessage;
10 use giterated_models::object::NetworkAnyObject;
11 use giterated_models::operation::NetworkAnyOperation;
12 use giterated_models::settings::{GetSettingError, SetSettingError, Setting};
8 use giterated_models::error::IntoInternalError;
9 use giterated_models::settings::Setting;
13 10 use giterated_models::value::GetValue;
14 11 use giterated_models::{
15 12 error::OperationError,
@@ -29,37 +26,78 @@ use crate::{
29 26 RuntimeMetadata, StackOperationState, SubstackBuilder,
30 27 };
31 28
32 pub type OperationHandler = HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure>;
29 pub type OperationHandler<OS> =
30 HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure, OS>;
33 31
34 pub type ValueGetter = HandlerWrapper<(AnyObject, String), AnyValue, AnyFailure>;
32 pub type ValueGetter<OS> = HandlerWrapper<(AnyObject, String), AnyValue, AnyFailure, OS>;
35 33
36 pub type SettingGetter = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure>;
34 pub type SettingGetter<OS> = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure, OS>;
37 35
38 pub type ValueChange = HandlerWrapper<(AnyObject, AnyValue), (), anyhow::Error>;
36 pub type ValueChange<OS> = HandlerWrapper<(AnyObject, AnyValue), (), anyhow::Error, OS>;
39 37
40 pub type SettingChange = HandlerWrapper<(AnyObject, AnySetting), (), anyhow::Error>;
38 pub type SettingChange<OS> = HandlerWrapper<(AnyObject, AnySetting), (), anyhow::Error, OS>;
41 39
42 #[derive(Default)]
43 pub struct GiteratedStack {
44 operation_handlers: HashMap<ObjectOperationPair<'static>, HandlerTree<OperationHandler>>,
45 value_getters: HashMap<ObjectValuePair<'static>, ValueGetter>,
46 setting_getters: HashMap<&'static str, SettingGetter>,
47 value_change: HashMap<ObjectValuePair<'static>, ValueChange>,
48 setting_change: HashMap<ObjectSettingPair<'static>, SettingChange>,
40 #[derive(Default, Clone)]
41 pub struct GiteratedStack<OS = StackOperationState> {
42 pub inner: Arc<GiteratedStackInner<OS>>,
43 }
44
45 impl<OS> Deref for GiteratedStack<OS> {
46 type Target = GiteratedStackInner<OS>;
47
48 fn deref(&self) -> &Self::Target {
49 &self.inner
50 }
51 }
52
53 pub struct GiteratedStackInner<OS = StackOperationState> {
54 operation_handlers: HashMap<ObjectOperationPair<'static>, HandlerTree<OperationHandler<OS>>>,
55 value_getters: HashMap<ObjectValuePair<'static>, ValueGetter<OS>>,
56 setting_getters: HashMap<&'static str, SettingGetter<OS>>,
57 value_change: HashMap<ObjectValuePair<'static>, ValueChange<OS>>,
58 setting_change: HashMap<ObjectSettingPair<'static>, SettingChange<OS>>,
49 59 metadata_providers: Vec<Box<dyn MetadataProvider>>,
50 60 pub metadata: RuntimeMetadata,
61 _marker: PhantomData<OS>,
51 62 }
52 63
53 impl Debug for GiteratedStack {
64 impl<OS> Default for GiteratedStackInner<OS> {
65 fn default() -> Self {
66 Self {
67 operation_handlers: Default::default(),
68 value_getters: Default::default(),
69 setting_getters: Default::default(),
70 value_change: Default::default(),
71 setting_change: Default::default(),
72 metadata_providers: Default::default(),
73 metadata: Default::default(),
74 _marker: Default::default(),
75 }
76 }
77 }
78
79 impl<OS> Debug for GiteratedStack<OS> {
54 80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 81 f.debug_struct("GiteratedStack").finish()
56 82 }
57 83 }
58 84
59 impl GiteratedStack {
85 pub struct GiteratedStackBuilder<OS> {
86 inner: GiteratedStackInner<OS>,
87 }
88
89 impl<OS> Default for GiteratedStackBuilder<OS> {
90 fn default() -> Self {
91 Self {
92 inner: Default::default(),
93 }
94 }
95 }
96
97 impl<OS: Clone> GiteratedStackBuilder<OS> {
60 98 pub fn merge_builder<S: GiteratedStackState>(
61 99 &mut self,
62 mut builder: SubstackBuilder<S>,
100 mut builder: SubstackBuilder<S, OS>,
63 101 ) -> &mut Self {
64 102 for (target, handler) in builder.operation_handlers {
65 103 let tree = self.get_or_create_tree(&target);
@@ -68,35 +106,55 @@ impl GiteratedStack {
68 106 }
69 107
70 108 for (target, handler) in builder.value_getters {
71 assert!(self.value_getters.insert(target, handler).is_none());
109 assert!(self.inner.value_getters.insert(target, handler).is_none());
72 110 }
73 111
74 112 for (target, handler) in builder.setting_getters {
75 assert!(self.setting_getters.insert(target, handler).is_none());
113 assert!(self.inner.setting_getters.insert(target, handler).is_none());
76 114 }
77 115
78 116 for (target, handler) in builder.value_change {
79 self.value_change.insert(target, handler);
117 self.inner.value_change.insert(target, handler);
80 118 }
81 119
82 120 for (target, handler) in builder.setting_change {
83 self.setting_change.insert(target, handler);
121 self.inner.setting_change.insert(target, handler);
84 122 }
85 123
86 self.metadata_providers
124 self.inner
125 .metadata_providers
87 126 .append(&mut builder.metadata_providers);
88 127
89 self.metadata.append(builder.metadata);
128 self.inner.metadata.append(builder.metadata);
90 129
91 130 self
92 131 }
93 132
94 pub async fn value_update<O>(
95 &self,
96 object: O,
97 new_value: AnyValue,
98 operation_state: &StackOperationState,
99 ) where
133 fn get_or_create_tree(
134 &mut self,
135 target: &ObjectOperationPair<'static>,
136 ) -> &mut HandlerTree<OperationHandler<OS>> {
137 if self.inner.operation_handlers.contains_key(target) {
138 self.inner.operation_handlers.get_mut(target).unwrap()
139 } else {
140 self.inner
141 .operation_handlers
142 .insert(target.clone(), HandlerTree::default());
143
144 self.inner.operation_handlers.get_mut(target).unwrap()
145 }
146 }
147
148 pub fn finish(self) -> GiteratedStack<OS> {
149 GiteratedStack {
150 inner: Arc::new(self.inner),
151 }
152 }
153 }
154
155 impl<OS: Clone + 'static> GiteratedStack<OS> {
156 pub async fn value_update<O>(&self, object: O, new_value: AnyValue, operation_state: &OS)
157 where
100 158 O: GiteratedObject + 'static,
101 159 {
102 160 trace!(
@@ -107,7 +165,7 @@ impl GiteratedStack {
107 165 let object = AnyObject::new(object);
108 166
109 167 // First, resolve a handler for the exact object value pair
110 if let Some(handler) = self.value_change.get(&new_value.kind()) {
168 if let Some(handler) = self.inner.value_change.get(&new_value.kind()) {
111 169 // TODO
112 170 let _ = handler
113 171 .handle((object.clone(), new_value.clone()), operation_state.clone())
@@ -119,7 +177,7 @@ impl GiteratedStack {
119 177 object_kind: "any",
120 178 value_kind: new_value.kind().value_kind,
121 179 };
122 if let Some(handler) = self.value_change.get(&target) {
180 if let Some(handler) = self.inner.value_change.get(&target) {
123 181 // TODO
124 182 let _ = handler
125 183 .handle((object.clone(), new_value.clone()), operation_state.clone())
@@ -130,7 +188,7 @@ impl GiteratedStack {
130 188 object_kind: O::object_name(),
131 189 value_kind: "any",
132 190 };
133 if let Some(handler) = self.value_change.get(&target) {
191 if let Some(handler) = self.inner.value_change.get(&target) {
134 192 // TODO
135 193 let _ = handler
136 194 .handle((object.clone(), new_value.clone()), operation_state.clone())
@@ -143,7 +201,7 @@ impl GiteratedStack {
143 201 object_kind: "any",
144 202 value_kind: "any",
145 203 };
146 if let Some(handler) = self.value_change.get(&target) {
204 if let Some(handler) = self.inner.value_change.get(&target) {
147 205 // TODO
148 206 let _ = handler
149 207 .handle((object.clone(), new_value.clone()), operation_state.clone())
@@ -151,19 +209,15 @@ impl GiteratedStack {
151 209 }
152 210 }
153 211
154 pub async fn setting_update<O, S>(
155 &self,
156 object: O,
157 new_setting: S,
158 operation_state: &StackOperationState,
159 ) where
212 pub async fn setting_update<O, S>(&self, object: O, new_setting: S, operation_state: &OS)
213 where
160 214 O: GiteratedObject + 'static,
161 215 S: Setting + 'static,
162 216 {
163 217 trace!("setting updated {}::{}", O::object_name(), S::name());
164 218 let target = ObjectSettingPair::from_types::<O, S>();
165 219
166 if let Some(handler) = self.setting_change.get(&target) {
220 if let Some(handler) = self.inner.setting_change.get(&target) {
167 221 let _ = handler
168 222 .handle(
169 223 (AnyObject::new(object), AnySetting::new::<O, S>(new_setting)),
@@ -190,15 +244,17 @@ impl GiteratedStack {
190 244 O: GiteratedObject + 'static + Clone,
191 245 S: Setting + 'static + Clone,
192 246 {
193 for provider in self.metadata_providers.iter() {
247 for provider in self.inner.metadata_providers.iter() {
194 248 if provider.provides_for(object as &dyn Any) {
195 249 let setting_meta = self
250 .inner
196 251 .metadata
197 252 .settings
198 253 .get(&ObjectSettingPair::from_types::<O, S>())
199 254 .ok_or_else(|| OperationError::Unhandled)?;
200 255
201 256 let object_meta = self
257 .inner
202 258 .metadata
203 259 .objects
204 260 .get(O::object_name())
@@ -227,7 +283,7 @@ impl GiteratedStack {
227 283 O: GiteratedObject + 'static + Clone,
228 284 S: Setting + 'static,
229 285 {
230 for provider in self.metadata_providers.iter() {
286 for provider in self.inner.metadata_providers.iter() {
231 287 if provider.provides_for(object as &dyn Any) {
232 288 trace!(
233 289 "Resolving setting {} for object {} from provider.",
@@ -236,12 +292,14 @@ impl GiteratedStack {
236 292 );
237 293
238 294 let setting_meta = self
295 .inner
239 296 .metadata
240 297 .settings
241 298 .get(&ObjectSettingPair::from_types::<O, S>())
242 299 .ok_or_else(|| OperationError::Unhandled)?;
243 300
244 301 let object_meta = self
302 .inner
245 303 .metadata
246 304 .objects
247 305 .get(O::object_name())
@@ -264,465 +322,15 @@ impl GiteratedStack {
264 322
265 323 Err(OperationError::Unhandled)
266 324 }
267
268 fn get_or_create_tree(
269 &mut self,
270 target: &ObjectOperationPair<'static>,
271 ) -> &mut HandlerTree<OperationHandler> {
272 if self.operation_handlers.contains_key(target) {
273 self.operation_handlers.get_mut(target).unwrap()
274 } else {
275 self.operation_handlers
276 .insert(target.clone(), HandlerTree::default());
277
278 self.operation_handlers.get_mut(target).unwrap()
279 }
280 }
281 325 }
282 326
283 impl GiteratedStack {
284 /// Handles a giterated network message, returning either a raw success
285 /// payload or a serialized error payload.
286 pub async fn handle_network_message(
287 &self,
288 message: AuthenticatedPayload,
289 operation_state: &StackOperationState,
290 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
291 let message: GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> =
292 message.into_message();
293
294 // Deserialize the object, also getting the object type's name
295 let (object_type, object) = {
296 let mut result = None;
297
298 for (object_type, object_meta) in self.metadata.objects.iter() {
299 if let Ok(object) = (object_meta.from_str)(&message.object.0) {
300 result = Some((object_type.clone(), object));
301 break;
302 }
303 }
304
305 result
306 }
307 .ok_or_else(|| OperationError::Unhandled)?;
308
309 trace!(
310 "Handling network message {}::<{}>",
311 message.operation,
312 object_type
313 );
314
315 if message.operation == "get_value" {
316 // Special case
317 let operation: GetValue = serde_json::from_slice(&message.payload.0).unwrap();
318
319 let result = self
320 .network_get_value(
321 object,
322 object_type.clone(),
323 operation.clone(),
324 operation_state,
325 )
326 .await;
327
328 // In the case of internal errors, attach context
329 let result = result.map_err(|err| match err {
330 OperationError::Operation(operation) => OperationError::Operation(operation),
331 OperationError::Internal(internal) => {
332 OperationError::Internal(internal.context(format!(
333 "{}::get_value::<{}> outcome",
334 object_type, operation.value_name
335 )))
336 }
337 OperationError::Unhandled => OperationError::Unhandled,
338 });
339
340 let result = result.map(|r| serde_json::to_vec(&r).unwrap());
341
342 return result;
343 } else if message.operation == "get_setting" {
344 let operation: GetSetting = serde_json::from_slice(&message.payload.0).unwrap();
345 let setting_meta = self
346 .metadata
347 .settings
348 .get(&ObjectSettingPair {
349 object_kind: &object_type,
350 setting_name: &operation.setting_name,
351 })
352 .ok_or_else(|| OperationError::Unhandled)?;
353 let raw_result = self
354 .get_setting(
355 object,
356 object_type.clone(),
357 operation.clone(),
358 operation_state,
359 )
360 .await;
361 return match raw_result {
362 Ok(success) => {
363 // Success is the setting type, serialize it
364 let serialized = (setting_meta.serialize)(success).unwrap();
365
366 Ok(serde_json::to_vec(&serialized).unwrap())
367 }
368 Err(err) => Err(match err {
369 OperationError::Operation(failure) => {
370 // We know how to resolve this type
371 let failure: GetSettingError = *failure.downcast().unwrap();
372
373 OperationError::Operation(serde_json::to_vec(&failure).unwrap())
374 }
375 OperationError::Internal(internal) => {
376 OperationError::Internal(internal.context(format!(
377 "{}::get_setting::<{}> handler outcome",
378 object_type, setting_meta.name
379 )))
380 }
381 OperationError::Unhandled => OperationError::Unhandled,
382 }),
383 };
384 } else if message.operation == "set_setting" {
385 let operation: SetSetting = serde_json::from_slice(&message.payload.0).unwrap();
386
387 trace!(
388 "Handling network {}::set_setting for {}",
389 object_type,
390 operation.setting_name
391 );
392
393 let setting_meta = self
394 .metadata
395 .settings
396 .get(&ObjectSettingPair {
397 object_kind: &object_type,
398 setting_name: &operation.setting_name,
399 })
400 // TODO: Check this
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 ))?;
408
409 let setting = (setting_meta.deserialize)(operation.value)
410 .as_internal_error_with_context(format!(
411 "deserializing setting {} for object {}",
412 operation.setting_name, object_type
413 ))?;
414
415 trace!(
416 "Deserialized setting {} for object {}",
417 operation.setting_name,
418 object_type,
419 );
420
421 for provider in self.metadata_providers.iter() {
422 if provider.provides_for(object.deref()) {
423 trace!(
424 "Resolved setting provider for setting {} for object {}",
425 operation.setting_name,
426 object_type,
427 );
428
429 let object_meta = self
430 .metadata
431 .objects
432 .get(&object_type)
433 .ok_or_else(|| OperationError::Unhandled)?;
434
435 let raw_result = provider
436 .write(object.clone(), object_meta, setting.clone(), setting_meta)
437 .await;
438
439 return match raw_result {
440 Ok(_) => {
441 (setting_meta.setting_updated)(
442 object,
443 setting,
444 operation_state.runtime.clone(),
445 operation_state,
446 )
447 .await;
448
449 Ok(serde_json::to_vec(&()).unwrap())
450 }
451 Err(e) => Err(OperationError::Internal(e.context(format!(
452 "writing object {} setting {}",
453 object_type, operation.setting_name
454 )))),
455 };
456 }
457
458 trace!(
459 "Failed to resolve setting provider for setting {} for object {}",
460 operation.setting_name,
461 object_type,
462 );
463 }
464 }
465
466 let target = ObjectOperationPair {
467 object_name: &object_type,
468 operation_name: &message.operation,
469 };
470
471 // Resolve the target operations from the handlers table
472 let handler = self
473 .operation_handlers
474 .get(&target)
475 .ok_or_else(|| OperationError::Unhandled)?;
476
477 trace!(
478 "Resolved operation handler for network message {}::<{}>",
479 message.operation,
480 object_type
481 );
482
483 // Deserialize the operation
484 let meta = self
485 .metadata
486 .operations
487 .get(&target)
488 .ok_or_else(|| OperationError::Unhandled)?;
489
490 let operation =
491 (meta.deserialize)(&message.payload.0).as_internal_error_with_context(format!(
492 "deserializing operation {}::{}",
493 target.object_name, target.operation_name
494 ))?;
495
496 trace!(
497 "Deserialized operation for network message {}::<{}>",
498 message.operation,
499 object_type
500 );
501
502 trace!(
503 "Calling handler for network message {}::<{}>",
504 message.operation,
505 object_type
506 );
507
508 // Get the raw result of the operation, where the return values are boxed.
509 let raw_result = handler
510 .handle((object.clone(), operation.clone()), operation_state.clone())
511 .await;
512
513 trace!(
514 "Finished handling network message {}::<{}>",
515 message.operation,
516 object_type
517 );
518
519 // Deserialize the raw result for the network
520 match raw_result {
521 Ok(success) => Ok((meta.serialize_success)(success).as_internal_error()?),
522 Err(err) => Err(match err {
523 OperationError::Operation(failure) => {
524 OperationError::Operation((meta.serialize_error)(failure).as_internal_error()?)
525 }
526 OperationError::Internal(internal) => {
527 OperationError::Internal(internal.context(format!(
528 "operation {}::{} handler outcome",
529 target.object_name, target.operation_name
530 )))
531 }
532 OperationError::Unhandled => OperationError::Unhandled,
533 }),
534 }
535 }
536
537 pub async fn network_get_value(
538 &self,
539 object: AnyObject,
540 object_kind: String,
541 operation: GetValue,
542 operation_state: &StackOperationState,
543 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
544 trace!("Handling network get_value for {}", operation.value_name);
545
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)?;
607
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 }
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)?;
649
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 }
671 }
672 }
673
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 )
683 .await
684 {
685 Ok(success) => {
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)?;
692
693 return Ok((value_meta.serialize)(success).as_internal_error()?);
694 }
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 }
712 }
713 }
714 }
715 }
716
717 Err(OperationError::Unhandled)
718 }
719
327 impl<OS> GiteratedStack<OS> {
720 328 pub async fn get_setting(
721 329 &self,
722 330 object: AnyObject,
723 331 object_kind: String,
724 332 operation: GetSetting,
725 _operation_state: &StackOperationState,
333 _operation_state: &OS,
726 334 ) -> Result<AnySetting, OperationError<Box<dyn Any + Send + Sync>>> {
727 335 trace!(
728 336 "Handling network {}::get_setting for {}",
@@ -730,9 +338,10 @@ impl GiteratedStack {
730 338 operation.setting_name
731 339 );
732 340
733 for provider in self.metadata_providers.iter() {
341 for provider in self.inner.metadata_providers.iter() {
734 342 if provider.provides_for(object.deref()) {
735 343 let setting_meta = self
344 .inner
736 345 .metadata
737 346 .settings
738 347 .get(&ObjectSettingPair {
@@ -742,6 +351,7 @@ impl GiteratedStack {
742 351 .ok_or_else(|| OperationError::Unhandled)?;
743 352
744 353 let object_meta = self
354 .inner
745 355 .metadata
746 356 .objects
747 357 .get(&object_kind)
@@ -766,70 +376,16 @@ impl GiteratedStack {
766 376
767 377 Err(OperationError::Unhandled)
768 378 }
769
770 pub async fn network_set_setting(
771 &self,
772 object: AnyObject,
773 object_kind: String,
774 operation: SetSetting,
775 operation_state: &StackOperationState,
776 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
777 trace!(
778 "Handling network {}::set_setting for {}",
779 object_kind,
780 operation.setting_name
781 );
782
783 let target = ObjectSettingPair {
784 object_kind: &object_kind,
785 setting_name: &operation.setting_name,
786 };
787
788 let handler = self.setting_change.get(&target).unwrap();
789
790 let setting_meta = self
791 .metadata
792 .settings
793 .get(&ObjectSettingPair {
794 object_kind: &object_kind,
795 setting_name: &operation.setting_name,
796 })
797 .ok_or_else(|| OperationError::Unhandled)?;
798
799 let setting =
800 (setting_meta.deserialize)(operation.value).as_internal_error_with_context(format!(
801 "deserializing setting {} for object {}",
802 operation.setting_name, object_kind
803 ))?;
804
805 let raw_result = handler
806 .handle((object, setting.clone()), operation_state.clone())
807 .await;
808
809 match raw_result {
810 Ok(_) => {
811 // Serialize success, which is the value type itself
812 let serialized = serde_json::to_vec(&()).as_internal_error()?;
813
814 Ok(serialized)
815 }
816 Err(err) => Err(match err {
817 OperationError::Operation(operation) => OperationError::Internal(operation),
818 OperationError::Internal(internal) => OperationError::Internal(internal),
819 OperationError::Unhandled => OperationError::Unhandled,
820 }),
821 }
822 }
823 379 }
824 380
825 381 #[async_trait::async_trait(?Send)]
826 impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
382 impl<OS: Send + Sync + Clone + 'static> ObjectBackend<OS> for GiteratedStack<OS> {
827 383 async fn object_operation<O, D>(
828 384 &self,
829 385 in_object: O,
830 386 operation_name: &str,
831 387 payload: D,
832 operation_state: &StackOperationState,
388 operation_state: &OS,
833 389 ) -> Result<D::Success, OperationError<D::Failure>>
834 390 where
835 391 O: GiteratedObject + Debug + 'static,
@@ -848,6 +404,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
848 404 .ok_or_else(|| OperationError::Unhandled)?;
849 405
850 406 let value_meta = self
407 .inner
851 408 .metadata
852 409 .values
853 410 .get(&ObjectValuePair {
@@ -863,7 +420,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
863 420 value_name
864 421 );
865 422
866 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
423 if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair {
867 424 object_kind: "any",
868 425 value_kind: &get_value.value_name,
869 426 }) {
@@ -906,7 +463,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
906 463 }
907 464 }
908 465
909 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
466 if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair {
910 467 object_kind: O::object_name(),
911 468 value_kind: "any",
912 469 }) {
@@ -949,7 +506,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
949 506 }
950 507 }
951 508
952 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
509 if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair {
953 510 object_kind: "any",
954 511 value_kind: "any",
955 512 }) {
@@ -992,7 +549,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
992 549 }
993 550 }
994 551
995 if let Some(handler) = self.value_getters.get(&ObjectValuePair {
552 if let Some(handler) = self.inner.value_getters.get(&ObjectValuePair {
996 553 object_kind: O::object_name(),
997 554 value_kind: &get_value.value_name,
998 555 }) {
@@ -1080,7 +637,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
1080 637 let operation_type = {
1081 638 let mut operation_type = None;
1082 639
1083 for (target, operation_meta) in self.metadata.operations.iter() {
640 for (target, operation_meta) in self.inner.metadata.operations.iter() {
1084 641 // Skip elements that we know will not match
1085 642 if target.object_name != O::object_name() {
1086 643 continue;
@@ -1102,6 +659,7 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
1102 659
1103 660 // Resolve the handler from our handler tree
1104 661 let handler_tree = self
662 .inner
1105 663 .operation_handlers
1106 664 .get(&operation_type)
1107 665 .ok_or_else(|| OperationError::Unhandled)?;
@@ -1131,13 +689,13 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
1131 689 async fn get_object<O>(
1132 690 &self,
1133 691 object_str: &str,
1134 _operation_state: &StackOperationState,
1135 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>>
692 _operation_state: &OS,
693 ) -> Result<Object<OS, O, Self>, OperationError<ObjectRequestError>>
1136 694 where
1137 695 O: GiteratedObject + Debug + 'static,
1138 696 {
1139 697 // TODO: Authorization?
1140 for (_object_name, object_meta) in self.metadata.objects.iter() {
698 for (_object_name, object_meta) in self.inner.metadata.objects.iter() {
1141 699 if let Ok(object) = (object_meta.from_str)(object_str) {
1142 700 return Ok(unsafe {
1143 701 Object::new_unchecked(object.downcast_ref::<O>().unwrap().clone(), self.clone())
@@ -1150,12 +708,12 @@ impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
1150 708 }
1151 709
1152 710 // Placeholder
1153 impl GiteratedStack {
711 impl<OS> GiteratedStack<OS> {
1154 712 pub async fn new_operation_func(
1155 713 &self,
1156 714 _object: AnyObject,
1157 715 _operation: AnyOperation,
1158 _operation_state: StackOperationState,
716 _operation_state: OS,
1159 717 ) -> Result<AnySuccess, OperationError<AnyFailure>> {
1160 718 todo!()
1161 719 }

giterated-stack/src/substack.rs

View file
@@ -1,4 +1,4 @@
1 use std::{collections::HashMap, sync::Arc};
1 use std::{collections::HashMap, marker::PhantomData, sync::Arc};
2 2
3 3 use futures_util::FutureExt;
4 4 use giterated_models::{
@@ -15,23 +15,24 @@ use crate::{
15 15 handler::HandlerWrapper, provider::MetadataProvider, AnyFailure, AnyObject, AnyOperation,
16 16 AnySetting, AnySuccess, AnyValue, GiteratedStack, GiteratedStackState, IntoGiteratedHandler,
17 17 MaybeDynamicObject, MaybeDynamicValue, ObjectOperationPair, ObjectSettingPair, ObjectValuePair,
18 OperationHandler, RuntimeMetadata, SettingChange, SettingGetter, StackOperationState,
19 ValueChange, ValueGetter,
18 OperationHandler, OperationState, RuntimeMetadata, SettingChange, SettingGetter,
19 StackOperationState, ValueChange, ValueGetter,
20 20 };
21 21
22 pub struct SubstackBuilder<S: GiteratedStackState> {
23 pub(crate) operation_handlers: HashMap<ObjectOperationPair<'static>, OperationHandler>,
24 pub(crate) value_getters: HashMap<ObjectValuePair<'static>, ValueGetter>,
25 pub(crate) setting_getters: HashMap<&'static str, SettingGetter>,
22 pub struct SubstackBuilder<S: GiteratedStackState, OS> {
23 pub(crate) operation_handlers: HashMap<ObjectOperationPair<'static>, OperationHandler<OS>>,
24 pub(crate) value_getters: HashMap<ObjectValuePair<'static>, ValueGetter<OS>>,
25 pub(crate) setting_getters: HashMap<&'static str, SettingGetter<OS>>,
26 26 pub(crate) metadata: RuntimeMetadata,
27 pub(crate) value_change: HashMap<ObjectValuePair<'static>, ValueChange>,
27 pub(crate) value_change: HashMap<ObjectValuePair<'static>, ValueChange<OS>>,
28 28 pub(crate) metadata_providers: Vec<Box<dyn MetadataProvider>>,
29 pub(crate) setting_change: HashMap<ObjectSettingPair<'static>, SettingChange>,
29 pub(crate) setting_change: HashMap<ObjectSettingPair<'static>, SettingChange<OS>>,
30 30
31 31 pub(crate) state: S,
32 _marker: PhantomData<OS>,
32 33 }
33 34
34 impl<S: GiteratedStackState + 'static> SubstackBuilder<S> {
35 impl<S: GiteratedStackState + 'static, OS> SubstackBuilder<S, OS> {
35 36 pub fn new(state: S) -> Self {
36 37 Self {
37 38 operation_handlers: Default::default(),
@@ -42,11 +43,12 @@ impl<S: GiteratedStackState + 'static> SubstackBuilder<S> {
42 43 metadata_providers: Default::default(),
43 44 setting_change: Default::default(),
44 45 state,
46 _marker: PhantomData::default(),
45 47 }
46 48 }
47 49 }
48 50
49 impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
51 impl<S: Send + Sync + Clone + 'static, OS: Clone + 'static> SubstackBuilder<S, OS> {
50 52 /// Insert an operation handler into the runtime builder.
51 53 ///
52 54 /// # Type Registration
@@ -56,25 +58,20 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
56 58 where
57 59 O: GiteratedObject + Clone,
58 60 D: GiteratedOperation<O> + Clone,
59 H: IntoGiteratedHandler<
60 (O, D),
61 A,
62 S,
63 StackOperationState,
64 Result<D::Success, OperationError<D::Failure>>,
65 > + Send
61 H: IntoGiteratedHandler<(O, D), A, S, OS, Result<D::Success, OperationError<D::Failure>>>
62 + Send
66 63 + Sync
67 64 + 'static,
68 65 O: 'static,
69 66 D: 'static,
70 67 D::Failure: std::fmt::Debug + 'static,
71 68 D::Success: 'static,
69 OS: Clone,
72 70 {
73 71 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
74 72
75 73 let wrapped = wrapped.map(
76 |(any_object, any_operation): &(AnyObject, AnyOperation),
77 _state: &StackOperationState| {
74 |(any_object, any_operation): &(AnyObject, AnyOperation), _state: &OS| {
78 75 Ok((
79 76 any_object.downcast_ref::<O>().unwrap().clone(),
80 77 any_operation.downcast_ref::<D>().unwrap().clone(),
@@ -102,6 +99,94 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
102 99 self
103 100 }
104 101
102 /// Register a [`GiteratedObjectValue<O>`] type with the runtime, providing
103 /// its associated handler for [`GetValue`].
104 ///
105 /// # Type Registration
106 /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified
107 /// object type. It will **not** register the object type automatically.
108 pub fn dynamic_value<O, A, F>(&mut self, handler: F) -> &mut Self
109 where
110 O: MaybeDynamicObject + 'static,
111 F: IntoGiteratedHandler<
112 (O, String),
113 A,
114 S,
115 OS,
116 Result<AnyValue, OperationError<anyhow::Error>>,
117 > + Send
118 + Sync,
119 F: 'static,
120 {
121 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
122
123 let wrapped = wrapped.map(|(any_object, name): &(AnyObject, String), _state: &OS| {
124 Ok((O::from_any(any_object), name.clone()))
125 });
126
127 let wrapped = wrapped.map_return(|ret_val, _state| match ret_val {
128 Ok(success) => Ok(success.into_any()),
129 Err(err) => Err(match err {
130 OperationError::Operation(failure) => OperationError::Internal(failure.into()),
131 OperationError::Internal(err) => OperationError::Internal(err),
132 OperationError::Unhandled => OperationError::Unhandled,
133 }),
134 });
135
136 assert!(self
137 .value_getters
138 .insert(
139 ObjectValuePair {
140 object_kind: O::object_name(),
141 value_kind: "any"
142 },
143 wrapped
144 )
145 .is_none());
146
147 self
148 }
149
150 pub fn value_change<O, A, F, V>(&mut self, handler: F) -> &mut Self
151 where
152 F: IntoGiteratedHandler<(O, V), A, S, OS, Result<(), OperationError<anyhow::Error>>>
153 + Send
154 + Sync,
155 V: MaybeDynamicValue + Clone + 'static,
156 O: 'static + MaybeDynamicObject,
157 V: 'static,
158 F: 'static,
159 {
160 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
161
162 let wrapped = wrapped.map(
163 |(any_object, any_value): &(AnyObject, AnyValue), _state: &OS| {
164 Ok((O::from_any(any_object), V::from_any(any_value)))
165 },
166 );
167
168 assert!(self
169 .value_change
170 .insert(
171 ObjectValuePair {
172 object_kind: O::object_name(),
173 value_kind: V::value_name()
174 },
175 wrapped
176 )
177 .is_none());
178
179 self
180 }
181
182 pub fn object_metadata_provider(&mut self, provider: Box<dyn MetadataProvider>) -> &mut Self {
183 self.metadata_providers.push(provider);
184
185 self
186 }
187 }
188
189 impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S, StackOperationState> {
105 190 /// Register a [`GiteratedObject`] type with the runtime.
106 191 ///
107 192 /// # Type Registration
@@ -115,11 +200,10 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
115 200 move |_object: Instance,
116 201 operation: ObjectRequest,
117 202 _state: S,
118 _operation_state: StackOperationState,
119 stack: Arc<GiteratedStack>| {
203 stack: GiteratedStack<StackOperationState>| {
120 204 let operation = operation.clone();
121 205 async move {
122 for (_object_name, object_meta) in stack.metadata.objects.iter() {
206 for (_object_name, object_meta) in stack.inner.metadata.objects.iter() {
123 207 if (object_meta.from_str)(&operation.0).is_ok() {
124 208 return Ok(ObjectResponse(operation.0.clone()));
125 209 }
@@ -163,9 +247,9 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
163 247 (),
164 248 move |object: AnyObject,
165 249 setting: AnySetting,
166 _state: (),
167 operation_state: StackOperationState,
168 stack: Arc<GiteratedStack>| {
250 _state: _,
251 OperationState(operation_state): OperationState<StackOperationState>,
252 stack: GiteratedStack<StackOperationState>| {
169 253 trace!(
170 254 "value setting updated {}::{}",
171 255 O::object_name(),
@@ -194,8 +278,7 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
194 278 |object: AnyObject,
195 279 _name: String,
196 280 _state: _,
197 _operation_state: StackOperationState,
198 stack: Arc<GiteratedStack>| {
281 stack: GiteratedStack<StackOperationState>| {
199 282 info!("a setting handler called");
200 283 let object = object.clone();
201 284 async move {
@@ -218,105 +301,14 @@ impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
218 301
219 302 self
220 303 }
221
222 /// Register a [`GiteratedObjectValue<O>`] type with the runtime, providing
223 /// its associated handler for [`GetValue`].
224 ///
225 /// # Type Registration
226 /// This will register the provided [`GiteratedObjectValue`] type for its matching / specified
227 /// object type. It will **not** register the object type automatically.
228 pub fn dynamic_value<O, A, F>(&mut self, handler: F) -> &mut Self
229 where
230 O: MaybeDynamicObject + 'static,
231 F: IntoGiteratedHandler<
232 (O, String),
233 A,
234 S,
235 StackOperationState,
236 Result<AnyValue, OperationError<anyhow::Error>>,
237 > + Send
238 + Sync,
239 F: 'static,
240 {
241 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
242
243 let wrapped = wrapped.map(
244 |(any_object, name): &(AnyObject, String), _state: &StackOperationState| {
245 Ok((O::from_any(any_object), name.clone()))
246 },
247 );
248
249 let wrapped = wrapped.map_return(|ret_val, _state| match ret_val {
250 Ok(success) => Ok(success.into_any()),
251 Err(err) => Err(match err {
252 OperationError::Operation(failure) => OperationError::Internal(failure.into()),
253 OperationError::Internal(err) => OperationError::Internal(err),
254 OperationError::Unhandled => OperationError::Unhandled,
255 }),
256 });
257
258 assert!(self
259 .value_getters
260 .insert(
261 ObjectValuePair {
262 object_kind: O::object_name(),
263 value_kind: "any"
264 },
265 wrapped
266 )
267 .is_none());
268
269 self
270 }
271
272 pub fn value_change<O, A, F, V>(&mut self, handler: F) -> &mut Self
273 where
274 F: IntoGiteratedHandler<
275 (O, V),
276 A,
277 S,
278 StackOperationState,
279 Result<(), OperationError<anyhow::Error>>,
280 > + Send
281 + Sync,
282 V: MaybeDynamicValue + Clone + 'static,
283 O: 'static + MaybeDynamicObject,
284 V: 'static,
285 F: 'static,
286 {
287 let wrapped = HandlerWrapper::new(self.state.clone(), handler);
288
289 let wrapped = wrapped.map(
290 |(any_object, any_value): &(AnyObject, AnyValue), _state: &StackOperationState| {
291 Ok((O::from_any(any_object), V::from_any(any_value)))
292 },
293 );
294
295 assert!(self
296 .value_change
297 .insert(
298 ObjectValuePair {
299 object_kind: O::object_name(),
300 value_kind: V::value_name()
301 },
302 wrapped
303 )
304 .is_none());
305
306 self
307 }
308
309 pub fn object_metadata_provider(&mut self, provider: Box<dyn MetadataProvider>) -> &mut Self {
310 self.metadata_providers.push(provider);
311
312 self
313 }
314 304 }
315 305
316 306 // Placeholder
317 impl<S: Send + Sync + Clone + 'static> SubstackBuilder<S> {
307 impl<S: Send + Sync + Clone + 'static, OS> SubstackBuilder<S, OS> {
318 308 pub fn dynamic_operation<H>(&mut self, _handler: H) -> &mut Self {
319 todo!()
309 tracing::error!("Dynamic unimplemented");
310
311 self
320 312 }
321 313 }
322 314 #[derive(Debug, Clone, thiserror::Error)]