Re-expose Operation State in generics.
This is the worst code I have ever written. I hate the way this changes everything. ugh.
parent: tbd commit: 90db3e2
Showing 23 changed files with 858 insertions and 1383 deletions
Cargo.lock
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)] |