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

ambee/giterated

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

Major refactor to handler traits

Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Squashed commit of the following: commit 62e1ecf76ee31cda0bab4602d9d00fa0dc2f9158 Author: Amber <[email protected]> Date: Wed Oct 11 09:31:11 2023 -0500 Update commit dfd2d1b0b5d81ee3bc48f0321c6aceaa677e3b8b Author: Amber <[email protected]> Date: Wed Oct 11 09:31:07 2023 -0500 Major refactor to handler traits Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Removed dead and legacy code. I think... commit 57b4b398eff32e69f2f4b9700e42a1277a4d1055 Author: Amber <[email protected]> Date: Sun Oct 1 23:05:10 2023 -0500 New handler trait for giterated stack Refactor the old handler trait so it is more generic and can be used for specific kinds of handlers

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90c4780

Showing ⁨⁨30⁩ changed files⁩ with ⁨⁨3011⁩ insertions⁩ and ⁨⁨2362⁩ deletions⁩

Cargo.lock

View file
@@ -115,6 +115,15 @@ dependencies = [
115 115 ]
116 116
117 117 [[package]]
118 name = "async-lock"
119 version = "2.8.0"
120 source = "registry+https://github.com/rust-lang/crates.io-index"
121 checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
122 dependencies = [
123 "event-listener",
124 ]
125
126 [[package]]
118 127 name = "async-trait"
119 128 version = "0.1.73"
120 129 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -122,7 +131,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
122 131 dependencies = [
123 132 "proc-macro2",
124 133 "quote",
125 "syn 2.0.37",
134 "syn 2.0.38",
126 135 ]
127 136
128 137 [[package]]
@@ -222,10 +231,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
222 231 checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
223 232
224 233 [[package]]
234 name = "bytecount"
235 version = "0.6.4"
236 source = "registry+https://github.com/rust-lang/crates.io-index"
237 checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7"
238
239 [[package]]
225 240 name = "byteorder"
226 version = "1.4.3"
241 version = "1.5.0"
227 242 source = "registry+https://github.com/rust-lang/crates.io-index"
228 checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
243 checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
229 244
230 245 [[package]]
231 246 name = "bytes"
@@ -234,6 +249,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
234 249 checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
235 250
236 251 [[package]]
252 name = "camino"
253 version = "1.1.6"
254 source = "registry+https://github.com/rust-lang/crates.io-index"
255 checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
256 dependencies = [
257 "serde",
258 ]
259
260 [[package]]
261 name = "cargo-platform"
262 version = "0.1.4"
263 source = "registry+https://github.com/rust-lang/crates.io-index"
264 checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36"
265 dependencies = [
266 "serde",
267 ]
268
269 [[package]]
270 name = "cargo_metadata"
271 version = "0.14.2"
272 source = "registry+https://github.com/rust-lang/crates.io-index"
273 checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
274 dependencies = [
275 "camino",
276 "cargo-platform",
277 "semver",
278 "serde",
279 "serde_json",
280 ]
281
282 [[package]]
237 283 name = "cc"
238 284 version = "1.0.83"
239 285 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -348,6 +394,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
348 394 checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
349 395
350 396 [[package]]
397 name = "crossbeam-channel"
398 version = "0.5.8"
399 source = "registry+https://github.com/rust-lang/crates.io-index"
400 checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
401 dependencies = [
402 "cfg-if",
403 "crossbeam-utils",
404 ]
405
406 [[package]]
407 name = "crossbeam-epoch"
408 version = "0.9.15"
409 source = "registry+https://github.com/rust-lang/crates.io-index"
410 checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
411 dependencies = [
412 "autocfg",
413 "cfg-if",
414 "crossbeam-utils",
415 "memoffset",
416 "scopeguard",
417 ]
418
419 [[package]]
351 420 name = "crossbeam-queue"
352 421 version = "0.3.8"
353 422 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -484,23 +553,21 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
484 553
485 554 [[package]]
486 555 name = "errno"
487 version = "0.3.3"
556 version = "0.3.5"
488 557 source = "registry+https://github.com/rust-lang/crates.io-index"
489 checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
558 checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
490 559 dependencies = [
491 "errno-dragonfly",
492 560 "libc",
493 561 "windows-sys",
494 562 ]
495 563
496 564 [[package]]
497 name = "errno-dragonfly"
498 version = "0.1.2"
565 name = "error-chain"
566 version = "0.12.4"
499 567 source = "registry+https://github.com/rust-lang/crates.io-index"
500 checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
568 checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
501 569 dependencies = [
502 "cc",
503 "libc",
570 "version_check",
504 571 ]
505 572
506 573 [[package]]
@@ -635,7 +702,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
635 702 dependencies = [
636 703 "proc-macro2",
637 704 "quote",
638 "syn 2.0.37",
705 "syn 2.0.38",
639 706 ]
640 707
641 708 [[package]]
@@ -745,6 +812,24 @@ dependencies = [
745 812 ]
746 813
747 814 [[package]]
815 name = "giterated-cache"
816 version = "0.1.0"
817 dependencies = [
818 "anyhow",
819 "async-trait",
820 "bincode",
821 "futures-util",
822 "giterated-models",
823 "giterated-stack",
824 "moka",
825 "serde",
826 "serde_json",
827 "thiserror",
828 "tokio",
829 "tracing",
830 ]
831
832 [[package]]
748 833 name = "giterated-daemon"
749 834 version = "0.1.0"
750 835 dependencies = [
@@ -821,6 +906,12 @@ dependencies = [
821 906 ]
822 907
823 908 [[package]]
909 name = "glob"
910 version = "0.3.1"
911 source = "registry+https://github.com/rust-lang/crates.io-index"
912 checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
913
914 [[package]]
824 915 name = "h2"
825 916 version = "0.3.21"
826 917 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -850,9 +941,9 @@ dependencies = [
850 941
851 942 [[package]]
852 943 name = "hashbrown"
853 version = "0.14.0"
944 version = "0.14.1"
854 945 source = "registry+https://github.com/rust-lang/crates.io-index"
855 checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
946 checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
856 947 dependencies = [
857 948 "ahash 0.8.3",
858 949 "allocator-api2",
@@ -864,7 +955,7 @@ version = "0.8.4"
864 955 source = "registry+https://github.com/rust-lang/crates.io-index"
865 956 checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
866 957 dependencies = [
867 "hashbrown 0.14.0",
958 "hashbrown 0.14.1",
868 959 ]
869 960
870 961 [[package]]
@@ -1051,12 +1142,12 @@ dependencies = [
1051 1142
1052 1143 [[package]]
1053 1144 name = "indexmap"
1054 version = "2.0.0"
1145 version = "2.0.2"
1055 1146 source = "registry+https://github.com/rust-lang/crates.io-index"
1056 checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
1147 checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
1057 1148 dependencies = [
1058 1149 "equivalent",
1059 "hashbrown 0.14.0",
1150 "hashbrown 0.14.1",
1060 1151 ]
1061 1152
1062 1153 [[package]]
@@ -1091,9 +1182,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
1091 1182
1092 1183 [[package]]
1093 1184 name = "jobserver"
1094 version = "0.1.26"
1185 version = "0.1.27"
1095 1186 source = "registry+https://github.com/rust-lang/crates.io-index"
1096 checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
1187 checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
1097 1188 dependencies = [
1098 1189 "libc",
1099 1190 ]
@@ -1132,9 +1223,9 @@ dependencies = [
1132 1223
1133 1224 [[package]]
1134 1225 name = "libc"
1135 version = "0.2.148"
1226 version = "0.2.149"
1136 1227 source = "registry+https://github.com/rust-lang/crates.io-index"
1137 checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
1228 checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
1138 1229
1139 1230 [[package]]
1140 1231 name = "libgit2-sys"
@@ -1152,9 +1243,9 @@ dependencies = [
1152 1243
1153 1244 [[package]]
1154 1245 name = "libm"
1155 version = "0.2.7"
1246 version = "0.2.8"
1156 1247 source = "registry+https://github.com/rust-lang/crates.io-index"
1157 checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
1248 checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
1158 1249
1159 1250 [[package]]
1160 1251 name = "libsqlite3-sys"
@@ -1195,9 +1286,9 @@ dependencies = [
1195 1286
1196 1287 [[package]]
1197 1288 name = "linux-raw-sys"
1198 version = "0.4.7"
1289 version = "0.4.10"
1199 1290 source = "registry+https://github.com/rust-lang/crates.io-index"
1200 checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
1291 checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
1201 1292
1202 1293 [[package]]
1203 1294 name = "lock_api"
@@ -1216,6 +1307,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1216 1307 checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
1217 1308
1218 1309 [[package]]
1310 name = "mach2"
1311 version = "0.4.1"
1312 source = "registry+https://github.com/rust-lang/crates.io-index"
1313 checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8"
1314 dependencies = [
1315 "libc",
1316 ]
1317
1318 [[package]]
1219 1319 name = "md-5"
1220 1320 version = "0.10.6"
1221 1321 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1227,9 +1327,18 @@ dependencies = [
1227 1327
1228 1328 [[package]]
1229 1329 name = "memchr"
1230 version = "2.6.3"
1330 version = "2.6.4"
1231 1331 source = "registry+https://github.com/rust-lang/crates.io-index"
1232 checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
1332 checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
1333
1334 [[package]]
1335 name = "memoffset"
1336 version = "0.9.0"
1337 source = "registry+https://github.com/rust-lang/crates.io-index"
1338 checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
1339 dependencies = [
1340 "autocfg",
1341 ]
1233 1342
1234 1343 [[package]]
1235 1344 name = "mime"
@@ -1264,6 +1373,30 @@ dependencies = [
1264 1373 ]
1265 1374
1266 1375 [[package]]
1376 name = "moka"
1377 version = "0.12.1"
1378 source = "registry+https://github.com/rust-lang/crates.io-index"
1379 checksum = "d8017ec3548ffe7d4cef7ac0e12b044c01164a74c0f3119420faeaf13490ad8b"
1380 dependencies = [
1381 "async-lock",
1382 "async-trait",
1383 "crossbeam-channel",
1384 "crossbeam-epoch",
1385 "crossbeam-utils",
1386 "futures-util",
1387 "once_cell",
1388 "parking_lot",
1389 "quanta",
1390 "rustc_version",
1391 "skeptic",
1392 "smallvec",
1393 "tagptr",
1394 "thiserror",
1395 "triomphe",
1396 "uuid",
1397 ]
1398
1399 [[package]]
1267 1400 name = "native-tls"
1268 1401 version = "0.2.11"
1269 1402 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1352,9 +1485,9 @@ dependencies = [
1352 1485
1353 1486 [[package]]
1354 1487 name = "num-traits"
1355 version = "0.2.16"
1488 version = "0.2.17"
1356 1489 source = "registry+https://github.com/rust-lang/crates.io-index"
1357 checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
1490 checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
1358 1491 dependencies = [
1359 1492 "autocfg",
1360 1493 "libm",
@@ -1414,7 +1547,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
1414 1547 dependencies = [
1415 1548 "proc-macro2",
1416 1549 "quote",
1417 "syn 2.0.37",
1550 "syn 2.0.38",
1418 1551 ]
1419 1552
1420 1553 [[package]]
@@ -1570,14 +1703,41 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
1570 1703
1571 1704 [[package]]
1572 1705 name = "proc-macro2"
1573 version = "1.0.67"
1706 version = "1.0.69"
1574 1707 source = "registry+https://github.com/rust-lang/crates.io-index"
1575 checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
1708 checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
1576 1709 dependencies = [
1577 1710 "unicode-ident",
1578 1711 ]
1579 1712
1580 1713 [[package]]
1714 name = "pulldown-cmark"
1715 version = "0.9.3"
1716 source = "registry+https://github.com/rust-lang/crates.io-index"
1717 checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
1718 dependencies = [
1719 "bitflags 1.3.2",
1720 "memchr",
1721 "unicase",
1722 ]
1723
1724 [[package]]
1725 name = "quanta"
1726 version = "0.11.1"
1727 source = "registry+https://github.com/rust-lang/crates.io-index"
1728 checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab"
1729 dependencies = [
1730 "crossbeam-utils",
1731 "libc",
1732 "mach2",
1733 "once_cell",
1734 "raw-cpuid",
1735 "wasi",
1736 "web-sys",
1737 "winapi",
1738 ]
1739
1740 [[package]]
1581 1741 name = "quote"
1582 1742 version = "1.0.33"
1583 1743 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1617,6 +1777,15 @@ dependencies = [
1617 1777 ]
1618 1778
1619 1779 [[package]]
1780 name = "raw-cpuid"
1781 version = "10.7.0"
1782 source = "registry+https://github.com/rust-lang/crates.io-index"
1783 checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
1784 dependencies = [
1785 "bitflags 1.3.2",
1786 ]
1787
1788 [[package]]
1620 1789 name = "redox_syscall"
1621 1790 version = "0.3.5"
1622 1791 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1627,9 +1796,9 @@ dependencies = [
1627 1796
1628 1797 [[package]]
1629 1798 name = "reqwest"
1630 version = "0.11.20"
1799 version = "0.11.22"
1631 1800 source = "registry+https://github.com/rust-lang/crates.io-index"
1632 checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
1801 checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
1633 1802 dependencies = [
1634 1803 "base64 0.21.4",
1635 1804 "bytes",
@@ -1655,6 +1824,7 @@ dependencies = [
1655 1824 "serde",
1656 1825 "serde_json",
1657 1826 "serde_urlencoded",
1827 "system-configuration",
1658 1828 "tokio",
1659 1829 "tokio-native-tls",
1660 1830 "tokio-rustls",
@@ -1718,10 +1888,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1718 1888 checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
1719 1889
1720 1890 [[package]]
1891 name = "rustc_version"
1892 version = "0.4.0"
1893 source = "registry+https://github.com/rust-lang/crates.io-index"
1894 checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
1895 dependencies = [
1896 "semver",
1897 ]
1898
1899 [[package]]
1721 1900 name = "rustix"
1722 version = "0.38.14"
1901 version = "0.38.18"
1723 1902 source = "registry+https://github.com/rust-lang/crates.io-index"
1724 checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
1903 checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c"
1725 1904 dependencies = [
1726 1905 "bitflags 2.4.0",
1727 1906 "errno",
@@ -1780,6 +1959,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1780 1959 checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
1781 1960
1782 1961 [[package]]
1962 name = "same-file"
1963 version = "1.0.6"
1964 source = "registry+https://github.com/rust-lang/crates.io-index"
1965 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1966 dependencies = [
1967 "winapi-util",
1968 ]
1969
1970 [[package]]
1783 1971 name = "schannel"
1784 1972 version = "0.1.22"
1785 1973 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1839,9 +2027,9 @@ dependencies = [
1839 2027
1840 2028 [[package]]
1841 2029 name = "semver"
1842 version = "1.0.19"
2030 version = "1.0.20"
1843 2031 source = "registry+https://github.com/rust-lang/crates.io-index"
1844 checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
2032 checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
1845 2033 dependencies = [
1846 2034 "serde",
1847 2035 ]
@@ -1863,7 +2051,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
1863 2051 dependencies = [
1864 2052 "proc-macro2",
1865 2053 "quote",
1866 "syn 2.0.37",
2054 "syn 2.0.38",
1867 2055 ]
1868 2056
1869 2057 [[package]]
@@ -1922,9 +2110,9 @@ dependencies = [
1922 2110
1923 2111 [[package]]
1924 2112 name = "sharded-slab"
1925 version = "0.1.4"
2113 version = "0.1.7"
1926 2114 source = "registry+https://github.com/rust-lang/crates.io-index"
1927 checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
2115 checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
1928 2116 dependencies = [
1929 2117 "lazy_static",
1930 2118 ]
@@ -1961,6 +2149,21 @@ dependencies = [
1961 2149 ]
1962 2150
1963 2151 [[package]]
2152 name = "skeptic"
2153 version = "0.13.7"
2154 source = "registry+https://github.com/rust-lang/crates.io-index"
2155 checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
2156 dependencies = [
2157 "bytecount",
2158 "cargo_metadata",
2159 "error-chain",
2160 "glob",
2161 "pulldown-cmark",
2162 "tempfile",
2163 "walkdir",
2164 ]
2165
2166 [[package]]
1964 2167 name = "slab"
1965 2168 version = "0.4.9"
1966 2169 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2067,7 +2270,7 @@ dependencies = [
2067 2270 "futures-util",
2068 2271 "hashlink",
2069 2272 "hex",
2070 "indexmap 2.0.0",
2273 "indexmap 2.0.2",
2071 2274 "log",
2072 2275 "memchr",
2073 2276 "native-tls",
@@ -2261,9 +2464,9 @@ dependencies = [
2261 2464
2262 2465 [[package]]
2263 2466 name = "syn"
2264 version = "2.0.37"
2467 version = "2.0.38"
2265 2468 source = "registry+https://github.com/rust-lang/crates.io-index"
2266 checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
2469 checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
2267 2470 dependencies = [
2268 2471 "proc-macro2",
2269 2472 "quote",
@@ -2271,6 +2474,33 @@ dependencies = [
2271 2474 ]
2272 2475
2273 2476 [[package]]
2477 name = "system-configuration"
2478 version = "0.5.1"
2479 source = "registry+https://github.com/rust-lang/crates.io-index"
2480 checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
2481 dependencies = [
2482 "bitflags 1.3.2",
2483 "core-foundation",
2484 "system-configuration-sys",
2485 ]
2486
2487 [[package]]
2488 name = "system-configuration-sys"
2489 version = "0.5.0"
2490 source = "registry+https://github.com/rust-lang/crates.io-index"
2491 checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
2492 dependencies = [
2493 "core-foundation-sys",
2494 "libc",
2495 ]
2496
2497 [[package]]
2498 name = "tagptr"
2499 version = "0.2.0"
2500 source = "registry+https://github.com/rust-lang/crates.io-index"
2501 checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
2502
2503 [[package]]
2274 2504 name = "tempfile"
2275 2505 version = "3.8.0"
2276 2506 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2300,7 +2530,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
2300 2530 dependencies = [
2301 2531 "proc-macro2",
2302 2532 "quote",
2303 "syn 2.0.37",
2533 "syn 2.0.38",
2304 2534 ]
2305 2535
2306 2536 [[package]]
@@ -2358,9 +2588,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2358 2588
2359 2589 [[package]]
2360 2590 name = "tokio"
2361 version = "1.32.0"
2591 version = "1.33.0"
2362 2592 source = "registry+https://github.com/rust-lang/crates.io-index"
2363 checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
2593 checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
2364 2594 dependencies = [
2365 2595 "backtrace",
2366 2596 "bytes",
@@ -2383,7 +2613,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
2383 2613 dependencies = [
2384 2614 "proc-macro2",
2385 2615 "quote",
2386 "syn 2.0.37",
2616 "syn 2.0.38",
2387 2617 ]
2388 2618
2389 2619 [[package]]
@@ -2475,7 +2705,7 @@ version = "0.19.15"
2475 2705 source = "registry+https://github.com/rust-lang/crates.io-index"
2476 2706 checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
2477 2707 dependencies = [
2478 "indexmap 2.0.0",
2708 "indexmap 2.0.2",
2479 2709 "serde",
2480 2710 "serde_spanned",
2481 2711 "toml_datetime",
@@ -2509,7 +2739,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
2509 2739 dependencies = [
2510 2740 "proc-macro2",
2511 2741 "quote",
2512 "syn 2.0.37",
2742 "syn 2.0.38",
2513 2743 ]
2514 2744
2515 2745 [[package]]
@@ -2558,6 +2788,12 @@ dependencies = [
2558 2788 ]
2559 2789
2560 2790 [[package]]
2791 name = "triomphe"
2792 version = "0.1.9"
2793 source = "registry+https://github.com/rust-lang/crates.io-index"
2794 checksum = "0eee8098afad3fb0c54a9007aab6804558410503ad676d4633f9c2559a00ac0f"
2795
2796 [[package]]
2561 2797 name = "try-lock"
2562 2798 version = "0.2.4"
2563 2799 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2590,6 +2826,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2590 2826 checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
2591 2827
2592 2828 [[package]]
2829 name = "unicase"
2830 version = "2.7.0"
2831 source = "registry+https://github.com/rust-lang/crates.io-index"
2832 checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
2833 dependencies = [
2834 "version_check",
2835 ]
2836
2837 [[package]]
2593 2838 name = "unicode-bidi"
2594 2839 version = "0.3.13"
2595 2840 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2657,6 +2902,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2657 2902 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
2658 2903
2659 2904 [[package]]
2905 name = "uuid"
2906 version = "1.4.1"
2907 source = "registry+https://github.com/rust-lang/crates.io-index"
2908 checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
2909 dependencies = [
2910 "getrandom",
2911 ]
2912
2913 [[package]]
2660 2914 name = "valuable"
2661 2915 version = "0.1.0"
2662 2916 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2675,6 +2929,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2675 2929 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
2676 2930
2677 2931 [[package]]
2932 name = "walkdir"
2933 version = "2.4.0"
2934 source = "registry+https://github.com/rust-lang/crates.io-index"
2935 checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
2936 dependencies = [
2937 "same-file",
2938 "winapi-util",
2939 ]
2940
2941 [[package]]
2678 2942 name = "want"
2679 2943 version = "0.3.1"
2680 2944 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2710,7 +2974,7 @@ dependencies = [
2710 2974 "once_cell",
2711 2975 "proc-macro2",
2712 2976 "quote",
2713 "syn 2.0.37",
2977 "syn 2.0.38",
2714 2978 "wasm-bindgen-shared",
2715 2979 ]
2716 2980
@@ -2744,7 +3008,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
2744 3008 dependencies = [
2745 3009 "proc-macro2",
2746 3010 "quote",
2747 "syn 2.0.37",
3011 "syn 2.0.38",
2748 3012 "wasm-bindgen-backend",
2749 3013 "wasm-bindgen-shared",
2750 3014 ]
@@ -2794,6 +3058,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2794 3058 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
2795 3059
2796 3060 [[package]]
3061 name = "winapi-util"
3062 version = "0.1.6"
3063 source = "registry+https://github.com/rust-lang/crates.io-index"
3064 checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
3065 dependencies = [
3066 "winapi",
3067 ]
3068
3069 [[package]]
2797 3070 name = "winapi-x86_64-pc-windows-gnu"
2798 3071 version = "0.4.0"
2799 3072 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2876,9 +3149,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
2876 3149
2877 3150 [[package]]
2878 3151 name = "winnow"
2879 version = "0.5.15"
3152 version = "0.5.16"
2880 3153 source = "registry+https://github.com/rust-lang/crates.io-index"
2881 checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
3154 checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907"
2882 3155 dependencies = [
2883 3156 "memchr",
2884 3157 ]

Cargo.toml

View file
@@ -2,5 +2,6 @@
2 2 members = [
3 3 "giterated-daemon",
4 4 "giterated-models",
5 "giterated-stack"
5 "giterated-stack",
6 "giterated-cache"
6 7 ]
6 7 \ No newline at end of file

giterated-cache/Cargo.toml

View file
@@ -0,0 +1,20 @@
1 [package]
2 name = "giterated-cache"
3 version = "0.1.0"
4 edition = "2021"
5
6 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
8 [dependencies]
9 giterated-models = { path = "../giterated-models" }
10 async-trait = "0.1"
11 serde = { version = "1.0.188", features = [ "derive" ]}
12 serde_json = "1.0"
13 bincode = "1.3"
14 futures-util = "0.3"
15 tracing = "0.1"
16 tokio = { version = "1.32", features = [ "full" ] }
17 anyhow = "1"
18 thiserror = "1"
19 giterated-stack = { path = "../giterated-stack" }
20 moka = { version = "0.12.0", features = ["future"] }

giterated-cache/src/cache_get.rs

View file
@@ -0,0 +1,16 @@
1 // use std::sync::Arc;
2
3 // use giterated_models::error::OperationError;
4 // use giterated_stack::GiteratedStack;
5 // use serde_json::Value;
6
7 // use crate::{cache_update::AnyObject, CacheSubstack};
8
9 // pub async fn try_value_get(
10 // object: AnyObject<'_>,
11 // value_name: &str,
12 // cache: CacheSubstack,
13 // stack: Arc<GiteratedStack>,
14 // ) -> Result<Value, OperationError<anyhow::Error>> {
15 // todo!()
16 // }

giterated-cache/src/cache_update.rs

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

giterated-cache/src/lib.rs

View file
@@ -0,0 +1,25 @@
1 // pub mod cache_get;
2 // pub mod cache_update;
3
4 // use giterated_stack::{ObjectValuePair, SubstackBuilder};
5 // use moka::future::Cache;
6 // use serde_json::Value;
7
8 // #[derive(Clone)]
9 // pub struct CacheSubstack {
10 // cache: Cache<ObjectValuePair, Value>,
11 // }
12
13 // impl Default for CacheSubstack {
14 // fn default() -> Self {
15 // Self {
16 // cache: Cache::new(20_000),
17 // }
18 // }
19 // }
20
21 // impl CacheSubstack {
22 // pub fn into_substack(self) -> SubstackBuilder<Self> {
23 // todo!()
24 // }
25 // }

giterated-daemon/src/backend/mod.rs

View file
@@ -25,9 +25,8 @@ use giterated_models::repository::{
25 25 RepositoryLastCommitOfFileRequest, RepositoryStatistics, RepositoryStatisticsRequest,
26 26 RepositorySummary, RepositoryTreeEntry,
27 27 };
28 use giterated_models::settings::AnySetting;
28
29 29 use giterated_models::user::User;
30 use giterated_models::value::AnyValue;
31 30
32 31 #[async_trait]
33 32 pub trait RepositoryBackend {
@@ -137,14 +136,6 @@ pub trait AuthBackend {
137 136
138 137 #[async_trait::async_trait]
139 138 pub trait UserBackend: AuthBackend {
140 async fn get_value(&mut self, user: &User, name: &str) -> Result<AnyValue<User>, Error>;
141 async fn get_setting(&mut self, user: &User, name: &str) -> Result<AnySetting, Error>;
142 async fn write_setting(
143 &mut self,
144 user: &User,
145 name: &str,
146 setting: &Value,
147 ) -> Result<(), Error>;
148 139 async fn exists(&mut self, user: &User) -> Result<bool, Error>;
149 140 async fn repositories_for_user(
150 141 &mut self,
@@ -155,22 +146,14 @@ pub trait UserBackend: AuthBackend {
155 146
156 147 #[async_trait::async_trait]
157 148 pub trait MetadataBackend {
158 async fn user_get(&mut self, user: &User, name: &str) -> Result<AnySetting, Error>;
159 async fn user_write(
160 &mut self,
161 user: &User,
162 name: &str,
163 setting: AnySetting,
164 ) -> Result<(), Error>;
165 async fn repository_get(
166 &mut self,
167 repository: &Repository,
168 name: &str,
169 ) -> Result<AnySetting, Error>;
149 async fn user_get(&mut self, user: &User, name: &str) -> Result<Value, Error>;
150 async fn user_write(&mut self, user: &User, name: &str, setting: Value) -> Result<(), Error>;
151 async fn repository_get(&mut self, repository: &Repository, name: &str)
152 -> Result<Value, Error>;
170 153 async fn repository_write(
171 154 &mut self,
172 155 repository: &Repository,
173 156 name: &str,
174 setting: AnySetting,
157 setting: Value,
175 158 ) -> Result<(), Error>;
176 159 }

giterated-daemon/src/backend/settings.rs

View file
@@ -3,10 +3,11 @@ use std::sync::Arc;
3 3 use anyhow::Error;
4 4
5 5 use giterated_models::repository::Repository;
6 use giterated_models::settings::AnySetting;
6
7 7 use giterated_models::user::User;
8 8
9 9 use giterated_stack::GiteratedStack;
10 use serde_json::Value;
10 11 use sqlx::PgPool;
11 12 use tokio::sync::OnceCell;
12 13
@@ -19,7 +20,7 @@ pub struct DatabaseSettings {
19 20
20 21 #[async_trait::async_trait]
21 22 impl MetadataBackend for DatabaseSettings {
22 async fn user_get(&mut self, user: &User, name: &str) -> Result<AnySetting, Error> {
23 async fn user_get(&mut self, user: &User, name: &str) -> Result<Value, Error> {
23 24 let row = sqlx::query_as!(
24 25 UserSettingRow,
25 26 "SELECT * FROM user_settings WHERE username = $1 AND name = $2",
@@ -33,12 +34,7 @@ impl MetadataBackend for DatabaseSettings {
33 34
34 35 Ok(setting)
35 36 }
36 async fn user_write(
37 &mut self,
38 user: &User,
39 name: &str,
40 value: AnySetting,
41 ) -> Result<(), Error> {
37 async fn user_write(&mut self, user: &User, name: &str, value: Value) -> Result<(), Error> {
42 38 sqlx::query!("INSERT INTO user_settings VALUES ($1, $2, $3) ON CONFLICT (username, name) DO UPDATE SET value = $3",
43 39 user.username, name, serde_json::to_string(&value)?)
44 40 .execute(&self.pg_pool).await?;
@@ -50,7 +46,7 @@ impl MetadataBackend for DatabaseSettings {
50 46 &mut self,
51 47 repository: &Repository,
52 48 name: &str,
53 ) -> Result<AnySetting, Error> {
49 ) -> Result<Value, Error> {
54 50 let row = sqlx::query_as!(
55 51 RepositorySettingRow,
56 52 "SELECT * FROM repository_settings WHERE repository = $1 AND name = $2",
@@ -68,7 +64,7 @@ impl MetadataBackend for DatabaseSettings {
68 64 &mut self,
69 65 repository: &Repository,
70 66 name: &str,
71 value: AnySetting,
67 value: Value,
72 68 ) -> Result<(), Error> {
73 69 sqlx::query!("INSERT INTO repository_settings VALUES ($1, $2, $3) ON CONFLICT (repository, name) DO UPDATE SET value = $3",
74 70 repository.to_string(), name, serde_json::to_string(&value)?)

giterated-daemon/src/backend/user.rs

View file
@@ -5,9 +5,8 @@ use giterated_models::authenticated::UserAuthenticationToken;
5 5 use giterated_models::instance::{AuthenticationTokenRequest, Instance, RegisterAccountRequest};
6 6
7 7 use giterated_models::repository::{Repository, RepositorySummary};
8 use giterated_models::settings::{AnySetting, Setting};
9 use giterated_models::user::{Bio, DisplayName, User, UserParseError};
10 use giterated_models::value::AnyValue;
8 use giterated_models::user::User;
9
11 10 use giterated_stack::AuthenticatedUser;
12 11 use std::sync::Arc;
13 12
@@ -22,7 +21,7 @@ use rsa::{
22 21 };
23 22
24 23 use secrecy::ExposeSecret;
25 use serde_json::Value;
24
26 25 use sqlx::{Either, PgPool};
27 26 use tokio::sync::Mutex;
28 27
@@ -56,36 +55,6 @@ impl UserAuth {
56 55
57 56 #[async_trait::async_trait]
58 57 impl UserBackend for UserAuth {
59 async fn get_value(&mut self, user: &User, name: &str) -> Result<AnyValue<User>, Error> {
60 Ok(match name {
61 "display_name" => unsafe {
62 AnyValue::from_raw(self.get_setting(user, DisplayName::name()).await?.0)
63 },
64 "bio" => unsafe { AnyValue::from_raw(self.get_setting(user, Bio::name()).await?.0) },
65 _ => {
66 return Err(UserParseError.into());
67 }
68 })
69 }
70 async fn get_setting(&mut self, user: &User, name: &str) -> Result<AnySetting, Error> {
71 let mut provider = self.settings_provider.lock().await;
72
73 Ok(provider.user_get(user, name).await?)
74 }
75
76 async fn write_setting(
77 &mut self,
78 user: &User,
79 name: &str,
80 setting: &Value,
81 ) -> Result<(), Error> {
82 let mut provider = self.settings_provider.lock().await;
83
84 provider
85 .user_write(user, name, AnySetting(setting.clone()))
86 .await
87 }
88
89 58 async fn exists(&mut self, user: &User) -> Result<bool, Error> {
90 59 Ok(sqlx::query_as!(
91 60 UserRow,

giterated-daemon/src/database_backend/handler.rs

View file
@@ -1,11 +1,8 @@
1 1 use std::sync::Arc;
2 2
3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 3 use giterated_models::{
5 4 authenticated::UserAuthenticationToken,
6 error::{
7 GetValueError, InstanceError, IntoInternalError, OperationError, RepositoryError, UserError,
8 },
5 error::{InstanceError, IntoInternalError, OperationError, RepositoryError, UserError},
9 6 instance::{
10 7 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
11 8 },
@@ -18,584 +15,384 @@ use giterated_models::{
18 15 RepositoryInfoRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics,
19 16 RepositoryStatisticsRequest, RepositorySummary, RepositoryView, Visibility,
20 17 },
21 settings::{GetSetting, GetSettingError},
22 user::{Bio, DisplayName, User, UserRepositoriesRequest},
23 value::{AnyValue, GetValueTyped},
18 user::{User, UserRepositoriesRequest},
24 19 };
25 use giterated_stack::{AuthenticatedUser, AuthorizedInstance, GiteratedStack, StackOperationState};
26 use serde_json::Value;
20 use giterated_stack::{AuthenticatedUser, GiteratedStack, StackOperationState};
27 21
28 22 use super::DatabaseBackend;
29 23
30 pub fn user_get_repositories(
31 object: &User,
24 pub async fn user_get_repositories(
25 object: User,
32 26 _operation: UserRepositoriesRequest,
33 27 state: DatabaseBackend,
34 28 _operation_state: StackOperationState,
35 29 requester: Option<AuthenticatedUser>,
36 ) -> LocalBoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
30 ) -> Result<Vec<RepositorySummary>, OperationError<UserError>> {
37 31 let object = object.clone();
38 32
39 async move {
40 let mut user_backend = state.user_backend.lock().await;
41 let repositories_response = user_backend
42 .repositories_for_user(&requester, &object)
43 .await
44 .as_internal_error()?;
45 drop(user_backend);
46 let mut repositories_backend = state.repository_backend.lock().await;
47
48 let mut repositories = vec![];
49
50 for repository in repositories_response {
51 if repositories_backend
52 .exists(&requester, &repository.repository)
53 .await
54 .as_internal_error()?
55 {
56 repositories.push(repository);
57 }
58 }
59
60 Ok(repositories)
61 }
62 .boxed_local()
63 }
33 let mut user_backend = state.user_backend.lock().await;
34 let repositories_response = user_backend
35 .repositories_for_user(&requester, &object)
36 .await
37 .as_internal_error()?;
38 drop(user_backend);
39 let mut repositories_backend = state.repository_backend.lock().await;
64 40
65 pub fn user_get_value(
66 object: &User,
67 operation: GetValueTyped<AnyValue<User>>,
68 state: DatabaseBackend,
69 ) -> LocalBoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
70 let object = object.clone();
41 let mut repositories = vec![];
71 42
72 async move {
73 let mut user_backend = state.user_backend.lock().await;
74 let value = user_backend
75 .get_value(&object, &operation.value_name)
43 for repository in repositories_response {
44 if repositories_backend
45 .exists(&requester, &repository.repository)
76 46 .await
77 .as_internal_error()?;
78
79 Ok(value)
47 .as_internal_error()?
48 {
49 repositories.push(repository);
50 }
80 51 }
81 .boxed_local()
82 }
83
84 pub fn user_get_setting(
85 object: &User,
86 operation: GetSetting,
87 state: DatabaseBackend,
88 ) -> LocalBoxFuture<'static, Result<Value, OperationError<GetSettingError>>> {
89 let object = object.clone();
90
91 async move {
92 let mut user_backend = state.user_backend.lock().await;
93 let value = user_backend
94 .get_setting(&object, &operation.setting_name)
95 .await
96 .as_internal_error()?;
97 52
98 Ok(value.0)
99 }
100 .boxed_local()
53 Ok(repositories)
101 54 }
102 55
103 pub fn repository_info(
104 object: &Repository,
56 pub async fn repository_info(
57 object: Repository,
105 58 operation: RepositoryInfoRequest,
106 59 state: DatabaseBackend,
107 60 operation_state: StackOperationState,
108 61 backend: Arc<GiteratedStack>,
109 62 requester: Option<AuthenticatedUser>,
110 ) -> LocalBoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
111 let object = object.clone();
112
113 async move {
114 let mut object = backend
115 .get_object::<Repository>(&object.to_string(), &operation_state)
116 .await
117 .unwrap();
118 let mut repository_backend = state.repository_backend.lock().await;
119 let tree = repository_backend
120 .repository_file_inspect(
121 &requester,
122 object.object(),
123 &RepositoryFileInspectRequest {
124 extra_metadata: operation.extra_metadata,
125 path: operation.path,
126 rev: operation.rev.clone(),
127 },
128 )
63 ) -> Result<RepositoryView, OperationError<RepositoryError>> {
64 let mut object = backend
65 .get_object::<Repository>(&object.to_string(), &operation_state)
66 .await
67 .unwrap();
68 let mut repository_backend = state.repository_backend.lock().await;
69 let tree = repository_backend
70 .repository_file_inspect(
71 &requester,
72 object.object(),
73 &RepositoryFileInspectRequest {
74 extra_metadata: operation.extra_metadata,
75 path: operation.path.clone(),
76 rev: operation.rev.clone(),
77 },
78 )
79 .await
80 .as_internal_error()?;
81
82 let statistics = repository_backend
83 .repository_get_statistics(
84 &requester,
85 object.object(),
86 &RepositoryStatisticsRequest {
87 rev: operation.rev.clone(),
88 },
89 )
90 .await
91 .as_internal_error()?;
92 drop(repository_backend);
93
94 let info = RepositoryView {
95 name: object.object().name.clone(),
96 owner: object.object().owner.clone(),
97 description: object.get::<Description>(&operation_state).await.ok(),
98 visibility: object
99 .get::<Visibility>(&operation_state)
129 100 .await
130 .as_internal_error()?;
131
132 let statistics = repository_backend
133 .repository_get_statistics(
134 &requester,
135 object.object(),
136 &RepositoryStatisticsRequest {
137 rev: operation.rev.clone(),
138 },
139 )
101 .as_internal_error()?,
102 default_branch: object
103 .get::<DefaultBranch>(&operation_state)
140 104 .await
141 .as_internal_error()?;
142 drop(repository_backend);
143
144 let info = RepositoryView {
145 name: object.object().name.clone(),
146 owner: object.object().owner.clone(),
147 description: object.get::<Description>(&operation_state).await.ok(),
148 visibility: object
149 .get::<Visibility>(&operation_state)
150 .await
151 .as_internal_error()?,
152 default_branch: object
153 .get::<DefaultBranch>(&operation_state)
154 .await
155 .as_internal_error()?,
156 // TODO: Can't be a simple get function, this needs to be returned alongside the tree as this differs depending on the rev and path.
157 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
158 stats: statistics,
159 tree_rev: operation.rev,
160 tree,
161 };
162
163 Ok(info)
164 }
165 .boxed_local()
105 .as_internal_error()?,
106 // TODO: Can't be a simple get function, this needs to be returned alongside the tree as this differs depending on the rev and path.
107 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
108 stats: statistics,
109 tree_rev: operation.rev.clone(),
110 tree,
111 };
112
113 Ok(info)
166 114 }
167 115
168 pub fn repository_get_statistics(
169 object: &Repository,
116 pub async fn repository_get_statistics(
117 object: Repository,
170 118 operation: RepositoryStatisticsRequest,
171 119 state: DatabaseBackend,
172 120 operation_state: StackOperationState,
173 121 backend: Arc<GiteratedStack>,
174 122 requester: Option<AuthenticatedUser>,
175 ) -> LocalBoxFuture<'static, Result<RepositoryStatistics, OperationError<RepositoryError>>> {
176 let object = object.clone();
177
178 async move {
179 let object = backend
180 .get_object::<Repository>(&object.to_string(), &operation_state)
181 .await
182 .unwrap();
183
184 let mut repository_backend = state.repository_backend.lock().await;
185 let statistics = repository_backend
186 .repository_get_statistics(
187 &requester,
188 object.object(),
189 &RepositoryStatisticsRequest { rev: operation.rev },
190 )
191 .await
192 .as_internal_error()?;
193 drop(repository_backend);
194
195 Ok(statistics)
196 }
197 .boxed_local()
123 ) -> Result<RepositoryStatistics, OperationError<RepositoryError>> {
124 let object = backend
125 .get_object::<Repository>(&object.to_string(), &operation_state)
126 .await
127 .unwrap();
128
129 let mut repository_backend = state.repository_backend.lock().await;
130 let statistics = repository_backend
131 .repository_get_statistics(
132 &requester,
133 object.object(),
134 &RepositoryStatisticsRequest {
135 rev: operation.rev.clone(),
136 },
137 )
138 .await
139 .as_internal_error()?;
140 drop(repository_backend);
141
142 Ok(statistics)
198 143 }
199 144
200 pub fn repository_get_branches(
201 object: &Repository,
145 pub async fn repository_get_branches(
146 object: Repository,
202 147 operation: RepositoryBranchesRequest,
203 148 state: DatabaseBackend,
204 149 operation_state: StackOperationState,
205 150 backend: Arc<GiteratedStack>,
206 151 requester: Option<AuthenticatedUser>,
207 ) -> LocalBoxFuture<'static, Result<Vec<RepositoryBranch>, OperationError<RepositoryError>>> {
208 let object = object.clone();
209
210 async move {
211 let object = backend
212 .get_object::<Repository>(&object.to_string(), &operation_state)
213 .await
214 .unwrap();
215
216 let mut repository_backend = state.repository_backend.lock().await;
217 let branches = repository_backend
218 .repository_get_branches(&requester, object.object(), &operation)
219 .await
220 .as_internal_error()?;
221 drop(repository_backend);
222
223 Ok(branches)
224 }
225 .boxed_local()
152 ) -> Result<Vec<RepositoryBranch>, OperationError<RepositoryError>> {
153 let object = backend
154 .get_object::<Repository>(&object.to_string(), &operation_state)
155 .await
156 .unwrap();
157
158 let mut repository_backend = state.repository_backend.lock().await;
159 let branches = repository_backend
160 .repository_get_branches(&requester, object.object(), &operation)
161 .await
162 .as_internal_error()?;
163 drop(repository_backend);
164
165 Ok(branches)
226 166 }
227 167
228 pub fn repository_file_from_id(
229 object: &Repository,
168 pub async fn repository_file_from_id(
169 object: Repository,
230 170 operation: RepositoryFileFromIdRequest,
231 171 state: DatabaseBackend,
232 172 operation_state: StackOperationState,
233 173 backend: Arc<GiteratedStack>,
234 174
235 175 requester: Option<AuthenticatedUser>,
236 ) -> LocalBoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
237 let object = object.clone();
238
239 async move {
240 let object = backend
241 .get_object::<Repository>(&object.to_string(), &operation_state)
242 .await
243 .unwrap();
244
245 let mut repository_backend = state.repository_backend.lock().await;
246 let file = repository_backend
247 .repository_file_from_id(
248 &requester,
249 object.object(),
250 &RepositoryFileFromIdRequest(operation.0),
251 )
252 .await
253 .as_internal_error()?;
254 drop(repository_backend);
255
256 Ok(file)
257 }
258 .boxed_local()
176 ) -> Result<RepositoryFile, OperationError<RepositoryError>> {
177 let object = backend
178 .get_object::<Repository>(&object.to_string(), &operation_state)
179 .await
180 .unwrap();
181
182 let mut repository_backend = state.repository_backend.lock().await;
183 let file = repository_backend
184 .repository_file_from_id(
185 &requester,
186 object.object(),
187 &RepositoryFileFromIdRequest(operation.0.clone()),
188 )
189 .await
190 .as_internal_error()?;
191 drop(repository_backend);
192
193 Ok(file)
259 194 }
260 195
261 pub fn repository_file_from_path(
262 object: &Repository,
196 pub async fn repository_file_from_path(
197 object: Repository,
263 198 operation: RepositoryFileFromPathRequest,
264 199 state: DatabaseBackend,
265 200 operation_state: StackOperationState,
266 201 backend: Arc<GiteratedStack>,
267 202 requester: Option<AuthenticatedUser>,
268 ) -> LocalBoxFuture<'static, Result<(RepositoryFile, String), OperationError<RepositoryError>>> {
269 let object = object.clone();
270
271 async move {
272 let object = backend
273 .get_object::<Repository>(&object.to_string(), &operation_state)
274 .await
275 .unwrap();
276
277 let mut repository_backend = state.repository_backend.lock().await;
278 let file = repository_backend
279 .repository_file_from_path(
280 &requester,
281 object.object(),
282 &RepositoryFileFromPathRequest {
283 rev: operation.rev,
284 path: operation.path,
285 },
286 )
287 .await
288 .as_internal_error()?;
289 drop(repository_backend);
290
291 Ok(file)
292 }
293 .boxed_local()
203 ) -> Result<(RepositoryFile, String), OperationError<RepositoryError>> {
204 let object = backend
205 .get_object::<Repository>(&object.to_string(), &operation_state)
206 .await
207 .unwrap();
208
209 let mut repository_backend = state.repository_backend.lock().await;
210 let file = repository_backend
211 .repository_file_from_path(
212 &requester,
213 object.object(),
214 &RepositoryFileFromPathRequest {
215 rev: operation.rev.clone(),
216 path: operation.path.clone(),
217 },
218 )
219 .await
220 .as_internal_error()?;
221 drop(repository_backend);
222
223 Ok(file)
294 224 }
295 225
296 pub fn repository_last_commit_of_file(
297 object: &Repository,
226 pub async fn repository_last_commit_of_file(
227 object: Repository,
298 228 operation: RepositoryLastCommitOfFileRequest,
299 229 state: DatabaseBackend,
300 230 operation_state: StackOperationState,
301 231 backend: Arc<GiteratedStack>,
302 232 requester: Option<AuthenticatedUser>,
303 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
304 let object = object.clone();
305
306 async move {
307 let object = backend
308 .get_object::<Repository>(&object.to_string(), &operation_state)
309 .await
310 .unwrap();
311
312 let mut repository_backend = state.repository_backend.lock().await;
313 let commit = repository_backend
314 .repository_last_commit_of_file(
315 &requester,
316 object.object(),
317 &RepositoryLastCommitOfFileRequest {
318 start_commit: operation.start_commit,
319 path: operation.path,
320 },
321 )
322 .await
323 .as_internal_error()?;
324 drop(repository_backend);
325
326 Ok(commit)
327 }
328 .boxed_local()
233 ) -> Result<Commit, OperationError<RepositoryError>> {
234 let object = backend
235 .get_object::<Repository>(&object.to_string(), &operation_state)
236 .await
237 .unwrap();
238
239 let mut repository_backend = state.repository_backend.lock().await;
240 let commit = repository_backend
241 .repository_last_commit_of_file(
242 &requester,
243 object.object(),
244 &RepositoryLastCommitOfFileRequest {
245 start_commit: operation.start_commit.clone(),
246 path: operation.path.clone(),
247 },
248 )
249 .await
250 .as_internal_error()?;
251 drop(repository_backend);
252
253 Ok(commit)
329 254 }
330 255
331 pub fn repository_commit_by_id(
332 object: &Repository,
256 pub async fn repository_commit_by_id(
257 object: Repository,
333 258 operation: RepositoryCommitFromIdRequest,
334 259 state: DatabaseBackend,
335 260 operation_state: StackOperationState,
336 261 backend: Arc<GiteratedStack>,
337 262 requester: Option<AuthenticatedUser>,
338 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
339 let object = object.clone();
340
341 async move {
342 let object = backend
343 .get_object::<Repository>(&object.to_string(), &operation_state)
344 .await
345 .unwrap();
346
347 let mut repository_backend = state.repository_backend.lock().await;
348 let commit = repository_backend
349 .repository_commit_from_id(
350 &requester,
351 object.object(),
352 &RepositoryCommitFromIdRequest(operation.0),
353 )
354 .await
355 .as_internal_error()?;
356 drop(repository_backend);
357
358 Ok(commit)
359 }
360 .boxed_local()
263 ) -> Result<Commit, OperationError<RepositoryError>> {
264 let object = backend
265 .get_object::<Repository>(&object.to_string(), &operation_state)
266 .await
267 .unwrap();
268
269 let mut repository_backend = state.repository_backend.lock().await;
270 let commit = repository_backend
271 .repository_commit_from_id(
272 &requester,
273 object.object(),
274 &RepositoryCommitFromIdRequest(operation.0.clone()),
275 )
276 .await
277 .as_internal_error()?;
278 drop(repository_backend);
279
280 Ok(commit)
361 281 }
362 282
363 pub fn repository_diff(
364 object: &Repository,
283 pub async fn repository_diff(
284 object: Repository,
365 285 operation: RepositoryDiffRequest,
366 286 state: DatabaseBackend,
367 287 operation_state: StackOperationState,
368 288 backend: Arc<GiteratedStack>,
369 289 requester: Option<AuthenticatedUser>,
370 ) -> LocalBoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
371 let object = object.clone();
372
373 async move {
374 let object = backend
375 .get_object::<Repository>(&object.to_string(), &operation_state)
376 .await
377 .unwrap();
378
379 let mut repository_backend = state.repository_backend.lock().await;
380 let diff = repository_backend
381 .repository_diff(&requester, object.object(), &operation)
382 .await
383 .as_internal_error()?;
384 drop(repository_backend);
385
386 Ok(diff)
387 }
388 .boxed_local()
290 ) -> Result<RepositoryDiff, OperationError<RepositoryError>> {
291 let object = backend
292 .get_object::<Repository>(&object.to_string(), &operation_state)
293 .await
294 .unwrap();
295
296 let mut repository_backend = state.repository_backend.lock().await;
297 let diff = repository_backend
298 .repository_diff(&requester, object.object(), &operation)
299 .await
300 .as_internal_error()?;
301 drop(repository_backend);
302
303 Ok(diff)
389 304 }
390 305
391 pub fn repository_diff_patch(
392 object: &Repository,
306 pub async fn repository_diff_patch(
307 object: Repository,
393 308 operation: RepositoryDiffPatchRequest,
394 309 state: DatabaseBackend,
395 310 operation_state: StackOperationState,
396 311 backend: Arc<GiteratedStack>,
397 312 requester: Option<AuthenticatedUser>,
398 ) -> LocalBoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
399 let object = object.clone();
400
401 async move {
402 let object = backend
403 .get_object::<Repository>(&object.to_string(), &operation_state)
404 .await
405 .unwrap();
406
407 let mut repository_backend = state.repository_backend.lock().await;
408 let patch = repository_backend
409 .repository_diff_patch(&requester, object.object(), &operation)
410 .await
411 .as_internal_error()?;
412 drop(repository_backend);
413
414 Ok(patch)
415 }
416 .boxed_local()
313 ) -> Result<String, OperationError<RepositoryError>> {
314 let object = backend
315 .get_object::<Repository>(&object.to_string(), &operation_state)
316 .await
317 .unwrap();
318
319 let mut repository_backend = state.repository_backend.lock().await;
320 let patch = repository_backend
321 .repository_diff_patch(&requester, object.object(), &operation)
322 .await
323 .as_internal_error()?;
324 drop(repository_backend);
325
326 Ok(patch)
417 327 }
418 328
419 pub fn repository_commit_before(
420 object: &Repository,
329 pub async fn repository_commit_before(
330 object: Repository,
421 331 operation: RepositoryCommitBeforeRequest,
422 332 state: DatabaseBackend,
423 333 operation_state: StackOperationState,
424 334 backend: Arc<GiteratedStack>,
425 335 requester: Option<AuthenticatedUser>,
426 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
427 let object = object.clone();
428
429 async move {
430 let object = backend
431 .get_object::<Repository>(&object.to_string(), &operation_state)
432 .await
433 .unwrap();
434
435 let mut repository_backend = state.repository_backend.lock().await;
436 let file = repository_backend
437 .repository_commit_before(&requester, object.object(), &operation)
438 .await
439 .as_internal_error()?;
440 drop(repository_backend);
441
442 Ok(file)
443 }
444 .boxed_local()
336 ) -> Result<Commit, OperationError<RepositoryError>> {
337 let object = backend
338 .get_object::<Repository>(&object.to_string(), &operation_state)
339 .await
340 .unwrap();
341
342 let mut repository_backend = state.repository_backend.lock().await;
343 let file = repository_backend
344 .repository_commit_before(&requester, object.object(), &operation)
345 .await
346 .as_internal_error()?;
347 drop(repository_backend);
348
349 Ok(file)
445 350 }
446 351
447 pub fn instance_authentication_request(
448 object: &Instance,
352 pub async fn instance_authentication_request(
353 object: Instance,
449 354 operation: AuthenticationTokenRequest,
450 355 state: DatabaseBackend,
356 _operation_state: StackOperationState,
451 357 // Authorizes the request for SAME-INSTANCE
452 _authorized_instance: AuthorizedInstance,
453 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
454 let object = object.clone();
455 async move {
456 let mut backend = state.user_backend.lock().await;
457
458 backend.login(&object, operation).await.as_internal_error()
459 }
460 .boxed_local()
358 // _authorized_instance: AuthorizedInstance,
359 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
360 let mut backend = state.user_backend.lock().await;
361
362 backend
363 .login(&object, operation.clone())
364 .await
365 .as_internal_error()
461 366 }
462 367
463 pub fn instance_registration_request(
464 _object: &Instance,
368 pub async fn instance_registration_request(
369 _object: Instance,
465 370 operation: RegisterAccountRequest,
466 371 state: DatabaseBackend,
467 // Authorizes the request for SAME-INSTANCE
468 _authorized_instance: AuthorizedInstance,
469 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
470 async move {
471 let mut backend = state.user_backend.lock().await;
472
473 backend.register(operation).await.as_internal_error()
474 }
475 .boxed_local()
372 _operation_state: StackOperationState, // Authorizes the request for SAME-INSTANCE
373 // _authorized_instance: AuthorizedInstance,
374 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
375 let mut backend = state.user_backend.lock().await;
376
377 backend
378 .register(operation.clone())
379 .await
380 .as_internal_error()
476 381 }
477 382
478 pub fn instance_create_repository_request(
479 _object: &Instance,
383 pub async fn instance_create_repository_request(
384 _object: Instance,
480 385 operation: RepositoryCreateRequest,
481 386 state: DatabaseBackend,
387 _operation_state: StackOperationState,
482 388 requester: AuthenticatedUser,
483 389 // Authorizes the request for SAME-INSTANCE
484 _authorized_instance: AuthorizedInstance,
485 ) -> LocalBoxFuture<'static, Result<Repository, OperationError<InstanceError>>> {
486 async move {
487 let mut backend = state.repository_backend.lock().await;
488
489 backend
490 .create_repository(&requester, &operation)
491 .await
492 .as_internal_error()
493 }
494 .boxed_local()
495 }
496
497 pub fn user_get_value_display_name(
498 object: &User,
499 _operation: GetValueTyped<DisplayName>,
500 _state: DatabaseBackend,
501 stack: Arc<GiteratedStack>, // _requester: AuthorizedUser,
502 ) -> LocalBoxFuture<'static, Result<DisplayName, OperationError<GetValueError>>> {
503 let object = object.clone();
504
505 async move {
506 stack
507 .new_get_setting::<_, DisplayName>(&object)
508 .await
509 .as_internal_error()
510 }
511 .boxed_local()
512 }
513
514 pub fn user_get_value_bio(
515 object: &User,
516 _operation: GetValueTyped<Bio>,
517 _state: DatabaseBackend,
518 stack: Arc<GiteratedStack>,
519 ) -> LocalBoxFuture<'static, Result<Bio, OperationError<GetValueError>>> {
520 let object = object.clone();
521
522 async move {
523 stack
524 .new_get_setting::<_, Bio>(&object)
525 .await
526 .as_internal_error()
527 }
528 .boxed_local()
529 }
530
531 pub fn repository_get_value_description(
532 object: &Repository,
533 _operation: GetValueTyped<Description>,
534 _state: DatabaseBackend,
535 stack: Arc<GiteratedStack>,
536 ) -> LocalBoxFuture<'static, Result<Description, OperationError<GetValueError>>> {
537 let object = object.clone();
538
539 async move {
540 stack
541 .new_get_setting::<_, Description>(&object)
542 .await
543 .as_internal_error()
544 }
545 .boxed_local()
546 }
547
548 pub fn repository_get_value_visibility(
549 object: &Repository,
550 _operation: GetValueTyped<Visibility>,
551 _state: DatabaseBackend,
552 stack: Arc<GiteratedStack>,
553 ) -> LocalBoxFuture<'static, Result<Visibility, OperationError<GetValueError>>> {
554 let object = object.clone();
555
556 async move {
557 stack
558 .new_get_setting::<_, Visibility>(&object)
559 .await
560 .as_internal_error()
561 }
562 .boxed_local()
563 }
564
565 pub fn repository_get_default_branch(
566 object: &Repository,
567 _operation: GetValueTyped<DefaultBranch>,
568 _state: DatabaseBackend,
569 stack: Arc<GiteratedStack>,
570 ) -> LocalBoxFuture<'static, Result<DefaultBranch, OperationError<GetValueError>>> {
571 let object = object.clone();
572
573 async move {
574 stack
575 .new_get_setting::<_, DefaultBranch>(&object)
576 .await
577 .as_internal_error()
578 }
579 .boxed_local()
580 }
581
582 pub fn repository_get_latest_commit(
583 object: &Repository,
584 _operation: GetValueTyped<LatestCommit>,
585 state: DatabaseBackend,
586 _stack: Arc<GiteratedStack>,
587 ) -> LocalBoxFuture<'static, Result<LatestCommit, OperationError<GetValueError>>> {
588 let _object = object.clone();
589
590 async move {
591 let _backend = state.repository_backend.lock().await;
592
593 // stack
594 // .new_get_setting::<_, LatestCommit>(&*object)
595 // .await
596 // .as_internal_error()
597
598 Ok(LatestCommit(None))
599 }
600 .boxed_local()
390 // _authorized_instance: AuthorizedInstance,
391 ) -> Result<Repository, OperationError<InstanceError>> {
392 let mut backend = state.repository_backend.lock().await;
393
394 backend
395 .create_repository(&requester, &operation)
396 .await
397 .as_internal_error()
601 398 }

giterated-daemon/src/database_backend/mod.rs

View file
@@ -5,16 +5,13 @@ use std::any::Any;
5 5 use std::sync::Arc;
6 6
7 7 use anyhow::Context;
8 use giterated_models::error::OperationError;
8
9 9 use giterated_models::instance::Instance;
10 use giterated_models::object::{GiteratedObject, Object, ObjectRequestError};
11 use giterated_models::object_backend::ObjectBackend;
12 use giterated_models::operation::GiteratedOperation;
13 10 use giterated_models::repository::{DefaultBranch, Description, Repository, Visibility};
14 11 use giterated_models::user::{Bio, DisplayName, User};
15 12 use giterated_stack::provider::MetadataProvider;
16 use giterated_stack::{GiteratedStack, ObjectMeta, SubstackBuilder};
17 use giterated_stack::{SettingMeta, StackOperationState};
13 use giterated_stack::SettingMeta;
14 use giterated_stack::{AnyObject, AnySetting, GiteratedStack, ObjectMeta, SubstackBuilder};
18 15 use serde_json::Value;
19 16 use sqlx::PgPool;
20 17 use std::fmt::Debug;
@@ -27,37 +24,10 @@ use self::handler::{
27 24 instance_authentication_request, instance_create_repository_request,
28 25 instance_registration_request, repository_commit_before, repository_commit_by_id,
29 26 repository_diff, repository_diff_patch, repository_file_from_id, repository_file_from_path,
30 repository_get_branches, repository_get_default_branch, repository_get_latest_commit,
31 repository_get_statistics, repository_get_value_description, repository_get_value_visibility,
32 repository_info, repository_last_commit_of_file, user_get_repositories, user_get_value_bio,
33 user_get_value_display_name,
27 repository_get_branches, repository_get_statistics, repository_info,
28 repository_last_commit_of_file, user_get_repositories,
34 29 };
35 30
36 #[derive(Clone, Debug)]
37 pub struct Foobackend {}
38
39 #[async_trait::async_trait(?Send)]
40 impl ObjectBackend<StackOperationState> for Foobackend {
41 async fn object_operation<O: GiteratedObject + Debug, D: GiteratedOperation<O> + Debug>(
42 &self,
43 _object: O,
44 _operation: &str,
45 _payload: D,
46 _operation_state: &StackOperationState,
47 ) -> Result<D::Success, OperationError<D::Failure>> {
48 // We don't handle operations with this backend
49 Err(OperationError::Unhandled)
50 }
51
52 async fn get_object<O: GiteratedObject + Debug>(
53 &self,
54 _object_str: &str,
55 _operation_state: &StackOperationState,
56 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>> {
57 Err(OperationError::Unhandled)
58 }
59 }
60
61 31 /// A backend implementation which attempts to resolve data from the instance's database.
62 32 #[derive(Clone)]
63 33 #[allow(unused)]
@@ -105,8 +75,6 @@ impl DatabaseBackend {
105 75 .value_setting::<Repository, Visibility>()
106 76 .value_setting::<Repository, DefaultBranch>();
107 77
108 builder.value(repository_get_latest_commit);
109
110 78 builder
111 79 .operation(user_get_repositories)
112 80 .operation(instance_registration_request)
@@ -141,18 +109,18 @@ impl MetadataProvider for DatabaseBackend {
141 109
142 110 async fn write(
143 111 &self,
144 object: &(dyn Any + Send + Sync),
112 object: AnyObject,
145 113 _object_meta: &ObjectMeta,
146 setting: &(dyn Any + Send + Sync),
114 setting: AnySetting,
147 115 setting_meta: &SettingMeta,
148 116 ) -> Result<(), anyhow::Error> {
149 if let Some(repository) = object.downcast_ref::<Repository>() {
117 if let Some(repository) = object.0.downcast_ref::<Repository>() {
150 118 sqlx::query!("INSERT INTO repository_settings VALUES ($1, $2, $3) ON CONFLICT (repository, name) DO UPDATE SET value = $3",
151 119 repository.to_string(), setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?)
152 120 .execute(&self.pool).await?;
153 121
154 122 Ok(())
155 } else if let Some(user) = object.downcast_ref::<User>() {
123 } else if let Some(user) = object.0.downcast_ref::<User>() {
156 124 sqlx::query!("INSERT INTO user_settings VALUES ($1, $2, $3) ON CONFLICT (username, name) DO UPDATE SET value = $3",
157 125 user.username, setting_meta.name, serde_json::to_string(&(setting_meta.serialize)(setting).unwrap())?)
158 126 .execute(&self.pool).await?;
@@ -165,11 +133,11 @@ impl MetadataProvider for DatabaseBackend {
165 133
166 134 async fn read(
167 135 &self,
168 object: &(dyn Any + Send + Sync),
136 object: AnyObject,
169 137 _object_meta: &ObjectMeta,
170 138 setting_meta: &SettingMeta,
171 139 ) -> Result<Value, anyhow::Error> {
172 if let Some(repository) = object.downcast_ref::<Repository>() {
140 if let Some(repository) = object.0.downcast_ref::<Repository>() {
173 141 let row = sqlx::query_as!(
174 142 RepositorySettingRow,
175 143 "SELECT * FROM repository_settings WHERE repository = $1 AND name = $2",
@@ -183,7 +151,7 @@ impl MetadataProvider for DatabaseBackend {
183 151 serde_json::from_str(&row.value).context("deserializing setting from database")?;
184 152
185 153 Ok(setting)
186 } else if let Some(user) = object.downcast_ref::<User>() {
154 } else if let Some(user) = object.0.downcast_ref::<User>() {
187 155 info!("User for {}", setting_meta.name);
188 156 let row = sqlx::query_as!(
189 157 UserSettingRow,

giterated-models/src/authenticated.rs

View file
@@ -12,8 +12,8 @@ use serde::{Deserialize, Serialize};
12 12 use crate::{
13 13 instance::Instance,
14 14 message::GiteratedMessage,
15 object::{AnyObject, GiteratedObject},
16 operation::{AnyOperation, GiteratedOperation},
15 object::{GiteratedObject, NetworkAnyObject},
16 operation::{GiteratedOperation, NetworkAnyOperation},
17 17 user::User,
18 18 };
19 19
@@ -39,11 +39,11 @@ pub struct AuthenticatedPayload {
39 39 }
40 40
41 41 impl AuthenticatedPayload {
42 pub fn into_message(self) -> GiteratedMessage<AnyObject, AnyOperation> {
42 pub fn into_message(self) -> GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
43 43 GiteratedMessage {
44 object: AnyObject(self.object),
44 object: NetworkAnyObject(self.object),
45 45 operation: self.operation,
46 payload: AnyOperation(self.payload),
46 payload: NetworkAnyOperation(self.payload),
47 47 }
48 48 }
49 49 }

giterated-models/src/error.rs

View file
@@ -2,7 +2,7 @@ use std::fmt::Display;
2 2
3 3 use serde::{Deserialize, Serialize};
4 4
5 #[derive(Debug, thiserror::Error, Deserialize, Serialize)]
5 #[derive(Debug, thiserror::Error, Deserialize, Serialize, Clone)]
6 6 pub enum InstanceError {
7 7 #[error("registration failed")]
8 8 RegistrationFailure,
@@ -10,19 +10,19 @@ pub enum InstanceError {
10 10 AuthenticationFailed,
11 11 }
12 12
13 #[derive(Debug, thiserror::Error, Serialize, Deserialize)]
13 #[derive(Debug, thiserror::Error, Serialize, Deserialize, Clone)]
14 14 pub enum RepositoryError {}
15 15
16 #[derive(Debug, thiserror::Error, Deserialize, Serialize)]
16 #[derive(Debug, thiserror::Error, Deserialize, Serialize, Clone)]
17 17 pub enum UserError {}
18 18
19 #[derive(Debug, thiserror::Error, Serialize, Deserialize)]
19 #[derive(Debug, thiserror::Error, Serialize, Deserialize, Clone)]
20 20 pub enum GetValueError {
21 21 #[error("invalid object")]
22 22 InvalidObject,
23 23 }
24 24
25 #[derive(Debug, thiserror::Error)]
25 #[derive(Debug, thiserror::Error, Clone)]
26 26 #[error("unauthorized")]
27 27 pub struct UnauthorizedError;
28 28

giterated-models/src/message.rs

View file
@@ -1,8 +1,8 @@
1 1 use serde::Serialize;
2 2
3 3 use crate::{
4 object::{AnyObject, GiteratedObject},
5 operation::{AnyOperation, GiteratedOperation},
4 object::{GiteratedObject, NetworkAnyObject},
5 operation::{GiteratedOperation, NetworkAnyOperation},
6 6 };
7 7 use std::fmt::Debug;
8 8
@@ -42,7 +42,7 @@ mod string {
42 42 }
43 43 }
44 44
45 impl GiteratedMessage<AnyObject, AnyOperation> {
45 impl GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
46 46 pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
47 47 &self,
48 48 ) -> Result<GiteratedMessage<O, V>, ()> {

giterated-models/src/object.rs

View file
@@ -10,8 +10,8 @@ use crate::{
10 10 error::{GetValueError, OperationError},
11 11 object_backend::ObjectBackend,
12 12 operation::GiteratedOperation,
13 settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError, Setting},
14 value::{GetValueTyped, GiteratedObjectValue},
13 settings::{GetSetting, GetSettingError, SetSetting, SetSettingError, Setting},
14 value::{GetValue, GiteratedObjectValue},
15 15 };
16 16
17 17 mod operations;
@@ -75,15 +75,15 @@ impl<
75 75 ) -> Result<V, OperationError<GetValueError>> {
76 76 let result = self
77 77 .request(
78 GetValueTyped::<V> {
78 GetValue {
79 79 value_name: V::value_name().to_string(),
80 ty: Default::default(),
81 80 },
82 81 operation_state,
83 82 )
84 .await;
83 .await
84 .unwrap();
85 85
86 Ok(result?)
86 Ok(serde_json::from_value(result).unwrap())
87 87 }
88 88
89 89 pub async fn get_setting<S: Setting + Send + Clone + Debug>(
@@ -108,7 +108,7 @@ impl<
108 108 self.request(
109 109 SetSetting {
110 110 setting_name: S::name().to_string(),
111 value: AnySetting(serde_json::to_value(setting).unwrap()),
111 value: serde_json::to_value(setting).unwrap(),
112 112 },
113 113 operation_state,
114 114 )
@@ -119,7 +119,11 @@ impl<
119 119 &mut self,
120 120 request: R,
121 121 operation_state: &I,
122 ) -> Result<R::Success, OperationError<R::Failure>> {
122 ) -> Result<R::Success, OperationError<R::Failure>>
123 where
124 R::Success: Clone,
125 R::Failure: Clone,
126 {
123 127 self.backend
124 128 .object_operation(
125 129 self.inner.clone(),

giterated-models/src/object/operations.rs

View file
@@ -9,7 +9,7 @@ use super::GiteratedObject;
9 9 #[derive(Debug, Serialize, Deserialize, Clone)]
10 10 pub struct ObjectRequest(pub String);
11 11
12 #[derive(Serialize, Deserialize)]
12 #[derive(Serialize, Deserialize, Clone)]
13 13 pub struct ObjectResponse(pub String);
14 14
15 15 impl GiteratedOperation<Instance> for ObjectRequest {
@@ -18,7 +18,7 @@ impl GiteratedOperation<Instance> for ObjectRequest {
18 18 type Failure = ObjectRequestError;
19 19 }
20 20
21 #[derive(Debug, thiserror::Error, Serialize, Deserialize)]
21 #[derive(Debug, Clone, thiserror::Error, Serialize, Deserialize)]
22 22 pub enum ObjectRequestError {
23 23 #[error("error decoding the object")]
24 24 Deserialization(String),
@@ -27,9 +27,9 @@ pub enum ObjectRequestError {
27 27 #[derive(Clone, Debug, Serialize, Deserialize)]
28 28 #[serde(transparent)]
29 29 #[repr(transparent)]
30 pub struct AnyObject(pub String);
30 pub struct NetworkAnyObject(pub String);
31 31
32 impl GiteratedObject for AnyObject {
32 impl GiteratedObject for NetworkAnyObject {
33 33 fn object_name() -> &'static str {
34 34 "any"
35 35 }
@@ -39,13 +39,13 @@ impl GiteratedObject for AnyObject {
39 39 }
40 40 }
41 41
42 impl Display for AnyObject {
42 impl Display for NetworkAnyObject {
43 43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 44 f.write_str(&self.0)
45 45 }
46 46 }
47 47
48 impl FromStr for AnyObject {
48 impl FromStr for NetworkAnyObject {
49 49 type Err = Infallible;
50 50
51 51 fn from_str(s: &str) -> Result<Self, Self::Err> {

giterated-models/src/object_backend.rs

View file
@@ -17,7 +17,9 @@ pub trait ObjectBackend<S: Clone + Send + Sync>: Sized + Clone + Send {
17 17 ) -> Result<D::Success, OperationError<D::Failure>>
18 18 where
19 19 O: GiteratedObject + Debug + 'static,
20 D: GiteratedOperation<O> + Debug + 'static;
20 D: GiteratedOperation<O> + Debug + 'static,
21 D::Success: Clone,
22 D::Failure: Clone;
21 23
22 24 async fn get_object<O: GiteratedObject + Debug + 'static>(
23 25 &self,

giterated-models/src/operation.rs

View file
@@ -18,9 +18,9 @@ pub trait GiteratedOperation<O: GiteratedObject>:
18 18 #[derive(Clone, Debug, Serialize, Deserialize)]
19 19 #[serde(transparent)]
20 20 #[repr(transparent)]
21 pub struct AnyOperation(pub Vec<u8>);
21 pub struct NetworkAnyOperation(pub Vec<u8>);
22 22
23 impl<O: GiteratedObject> GiteratedOperation<O> for AnyOperation {
23 impl<O: GiteratedObject> GiteratedOperation<O> for NetworkAnyOperation {
24 24 type Success = Vec<u8>;
25 25
26 26 type Failure = Vec<u8>;

giterated-models/src/settings/mod.rs

View file
@@ -1,18 +1,13 @@
1 1 mod operations;
2 2
3 use std::{any::Any, sync::Arc};
4
3 5 pub use operations::*;
4 use serde::{de::DeserializeOwned, Deserialize, Serialize};
5 use serde_json::Value;
6 use serde::{de::DeserializeOwned, Serialize};
6 7
7 8 pub trait Setting: Serialize + DeserializeOwned + Send + Sync {
8 9 fn name() -> &'static str;
9 10 }
10 11
11 #[derive(Debug, Clone, Serialize, Deserialize)]
12 pub struct AnySetting(pub Value);
13
14 impl Setting for AnySetting {
15 fn name() -> &'static str {
16 "any"
17 }
18 }
12 #[derive(Debug, Clone)]
13 pub struct AnySetting(pub Arc<dyn Any + Send + Sync>);

giterated-models/src/settings/operations.rs

View file
@@ -6,8 +6,6 @@ use thiserror::Error;
6 6
7 7 use crate::{object::GiteratedObject, operation::GiteratedOperation};
8 8
9 use super::AnySetting;
10
11 9 #[derive(Serialize, Deserialize, Debug, Clone)]
12 10 pub struct GetSetting {
13 11 pub setting_name: String,
@@ -23,12 +21,12 @@ impl<O: GiteratedObject> GiteratedOperation<O> for GetSetting {
23 21 type Failure = GetSettingError;
24 22 }
25 23
26 #[derive(Error, Debug, Serialize, Deserialize)]
24 #[derive(Error, Debug, Serialize, Deserialize, Clone)]
27 25 pub enum GetSettingError {}
28 26 #[derive(Serialize, Deserialize, Debug, Clone)]
29 27 pub struct SetSetting {
30 28 pub setting_name: String,
31 pub value: AnySetting,
29 pub value: Value,
32 30 }
33 31
34 32 impl<O: GiteratedObject> GiteratedOperation<O> for SetSetting {
@@ -41,5 +39,5 @@ impl<O: GiteratedObject> GiteratedOperation<O> for SetSetting {
41 39 type Failure = SetSettingError;
42 40 }
43 41
44 #[derive(Error, Debug, Serialize, Deserialize)]
42 #[derive(Error, Debug, Serialize, Deserialize, Clone)]
45 43 pub enum SetSettingError {}

giterated-models/src/value.rs

View file
@@ -26,7 +26,6 @@ impl<O: GiteratedObject + Send> GiteratedOperation<O> for GetValue {
26 26
27 27 #[derive(Serialize, Deserialize, Debug, Clone)]
28 28 pub struct GetValueTyped<V: GiteratedObjectValue> {
29 pub value_name: String,
30 29 pub ty: PhantomData<V>,
31 30 }
32 31

giterated-stack/src/handler/handler_impl.rs

View file
@@ -0,0 +1,272 @@
1 use futures_util::Future;
2 use giterated_models::error::OperationError;
3
4 use crate::{HandlerResolvable, IntoGiteratedHandler};
5
6 #[async_trait::async_trait(?Send)]
7 impl<R1, S, OS, Success, Failure, H, Fut>
8 IntoGiteratedHandler<(R1,), (), S, OS, Result<Success, OperationError<Failure>>> for H
9 where
10 H: FnMut(R1, S, OS) -> Fut + Clone,
11 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
12 Success: 'static,
13 Failure: 'static,
14 R1: 'static,
15 S: 'static,
16 OS: 'static,
17 {
18 type Future = Fut;
19
20 async fn handle(
21 &self,
22 parameters: (R1,),
23 state: S,
24 operation_state: OS,
25 ) -> Result<Success, OperationError<Failure>> {
26 let (r1,) = parameters;
27 (self.clone())(r1, state, operation_state).await
28 }
29 }
30
31 #[async_trait::async_trait(?Send)]
32 impl<R1, A1, S, OS, Success, Failure, H, Fut>
33 IntoGiteratedHandler<(R1,), (A1,), S, OS, Result<Success, OperationError<Failure>>> for H
34 where
35 H: FnMut(R1, S, OS, A1) -> Fut + Clone,
36 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
37 Success: 'static,
38 Failure: 'static,
39 R1: 'static,
40 S: 'static,
41 OS: 'static,
42 A1: HandlerResolvable<(R1,), OS>,
43 A1::Error: Into<anyhow::Error>,
44 {
45 type Future = Fut;
46
47 async fn handle(
48 &self,
49 parameters: (R1,),
50 state: S,
51 operation_state: OS,
52 ) -> Result<Success, OperationError<Failure>> {
53 let a1 = A1::from_handler_state(&parameters, &operation_state)
54 .await
55 .map_err(|e| OperationError::Internal(e.into()))?;
56 let (r1,) = parameters;
57 (self.clone())(r1, state, operation_state, a1).await
58 }
59 }
60
61 #[async_trait::async_trait(?Send)]
62 impl<R1, A1, A2, S, OS, Success, Failure, H, Fut>
63 IntoGiteratedHandler<(R1,), (A1, A2), S, OS, Result<Success, OperationError<Failure>>> for H
64 where
65 H: FnMut(R1, S, OS, A1, A2) -> Fut + Clone,
66 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
67 Success: 'static,
68 Failure: 'static,
69 R1: 'static,
70 S: 'static,
71 OS: 'static,
72 A1: HandlerResolvable<(R1,), OS>,
73 A1::Error: Into<anyhow::Error>,
74 A2: HandlerResolvable<(R1,), OS>,
75 A2::Error: Into<anyhow::Error>,
76 {
77 type Future = Fut;
78
79 async fn handle(
80 &self,
81 parameters: (R1,),
82 state: S,
83 operation_state: OS,
84 ) -> Result<Success, OperationError<Failure>> {
85 let a1 = A1::from_handler_state(&parameters, &operation_state)
86 .await
87 .map_err(|e| OperationError::Internal(e.into()))?;
88 let a2 = A2::from_handler_state(&parameters, &operation_state)
89 .await
90 .map_err(|e| OperationError::Internal(e.into()))?;
91 let (r1,) = parameters;
92 (self.clone())(r1, state, operation_state, a1, a2).await
93 }
94 }
95
96 #[async_trait::async_trait(?Send)]
97 impl<R1, A1, A2, A3, S, OS, Success, Failure, H, Fut>
98 IntoGiteratedHandler<(R1,), (A1, A2, A3), S, OS, Result<Success, OperationError<Failure>>> for H
99 where
100 H: FnMut(R1, S, OS, A1, A2, A3) -> Fut + Clone,
101 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
102 Success: 'static,
103 Failure: 'static,
104 R1: 'static,
105 S: 'static,
106 OS: 'static,
107 A1: HandlerResolvable<(R1,), OS>,
108 A1::Error: Into<anyhow::Error>,
109 A2: HandlerResolvable<(R1,), OS>,
110 A2::Error: Into<anyhow::Error>,
111 A3: HandlerResolvable<(R1,), OS>,
112 A3::Error: Into<anyhow::Error>,
113 {
114 type Future = Fut;
115
116 async fn handle(
117 &self,
118 parameters: (R1,),
119 state: S,
120 operation_state: OS,
121 ) -> Result<Success, OperationError<Failure>> {
122 let a1 = A1::from_handler_state(&parameters, &operation_state)
123 .await
124 .map_err(|e| OperationError::Internal(e.into()))?;
125 let a2 = A2::from_handler_state(&parameters, &operation_state)
126 .await
127 .map_err(|e| OperationError::Internal(e.into()))?;
128 let a3 = A3::from_handler_state(&parameters, &operation_state)
129 .await
130 .map_err(|e| OperationError::Internal(e.into()))?;
131 let (r1,) = parameters;
132 (self.clone())(r1, state, operation_state, a1, a2, a3).await
133 }
134 }
135
136 #[async_trait::async_trait(?Send)]
137 impl<R1, R2, S, OS, Success, Failure, H, Fut>
138 IntoGiteratedHandler<(R1, R2), (), S, OS, Result<Success, OperationError<Failure>>> for H
139 where
140 H: FnMut(R1, R2, S, OS) -> Fut + Clone,
141 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
142 Success: 'static,
143 Failure: 'static,
144 R1: 'static,
145 R2: 'static,
146 S: 'static,
147 OS: 'static,
148 {
149 type Future = Fut;
150
151 async fn handle(
152 &self,
153 parameters: (R1, R2),
154 state: S,
155 operation_state: OS,
156 ) -> Result<Success, OperationError<Failure>> {
157 let (r1, r2) = parameters;
158 (self.clone())(r1, r2, state, operation_state).await
159 }
160 }
161
162 #[async_trait::async_trait(?Send)]
163 impl<R1, R2, A1, S, OS, Success, Failure, H, Fut>
164 IntoGiteratedHandler<(R1, R2), (A1,), S, OS, Result<Success, OperationError<Failure>>> for H
165 where
166 H: FnMut(R1, R2, S, OS, A1) -> Fut + Clone,
167 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
168 Success: 'static,
169 Failure: 'static,
170 R1: 'static,
171 R2: 'static,
172 S: 'static,
173 OS: 'static,
174 A1: HandlerResolvable<(R1, R2), OS>,
175 A1::Error: Into<anyhow::Error>,
176 {
177 type Future = Fut;
178
179 async fn handle(
180 &self,
181 parameters: (R1, R2),
182 state: S,
183 operation_state: OS,
184 ) -> Result<Success, OperationError<Failure>> {
185 let a1 = A1::from_handler_state(&parameters, &operation_state)
186 .await
187 .map_err(|e| OperationError::Internal(e.into()))?;
188
189 let (r1, r2) = parameters;
190 (self.clone())(r1, r2, state, operation_state, a1).await
191 }
192 }
193
194 #[async_trait::async_trait(?Send)]
195 impl<R1, R2, A1, A2, S, OS, Success, Failure, H, Fut>
196 IntoGiteratedHandler<(R1, R2), (A1, A2), S, OS, Result<Success, OperationError<Failure>>> for H
197 where
198 H: FnMut(R1, R2, S, OS, A1, A2) -> Fut + Clone,
199 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
200 Success: 'static,
201 Failure: 'static,
202 R1: 'static,
203 R2: 'static,
204 S: 'static,
205 OS: 'static,
206 A1: HandlerResolvable<(R1, R2), OS>,
207 A1::Error: Into<anyhow::Error>,
208 A2: HandlerResolvable<(R1, R2), OS>,
209 A2::Error: Into<anyhow::Error>,
210 {
211 type Future = Fut;
212
213 async fn handle(
214 &self,
215 parameters: (R1, R2),
216 state: S,
217 operation_state: OS,
218 ) -> Result<Success, OperationError<Failure>> {
219 let a1 = A1::from_handler_state(&parameters, &operation_state)
220 .await
221 .map_err(|e| OperationError::Internal(e.into()))?;
222 let a2 = A2::from_handler_state(&parameters, &operation_state)
223 .await
224 .map_err(|e| OperationError::Internal(e.into()))?;
225
226 let (r1, r2) = parameters;
227 (self.clone())(r1, r2, state, operation_state, a1, a2).await
228 }
229 }
230
231 #[async_trait::async_trait(?Send)]
232 impl<R1, R2, A1, A2, A3, S, OS, Success, Failure, H, Fut>
233 IntoGiteratedHandler<(R1, R2), (A1, A2, A3), S, OS, Result<Success, OperationError<Failure>>>
234 for H
235 where
236 H: FnMut(R1, R2, S, OS, A1, A2, A3) -> Fut + Clone,
237 Fut: Future<Output = Result<Success, OperationError<Failure>>> + 'static,
238 Success: 'static,
239 Failure: 'static,
240 R1: 'static,
241 R2: 'static,
242 S: 'static,
243 OS: 'static,
244 A1: HandlerResolvable<(R1, R2), OS>,
245 A1::Error: Into<anyhow::Error>,
246 A2: HandlerResolvable<(R1, R2), OS>,
247 A2::Error: Into<anyhow::Error>,
248 A3: HandlerResolvable<(R1, R2), OS>,
249 A3::Error: Into<anyhow::Error>,
250 {
251 type Future = Fut;
252
253 async fn handle(
254 &self,
255 parameters: (R1, R2),
256 state: S,
257 operation_state: OS,
258 ) -> Result<Success, OperationError<Failure>> {
259 let a1 = A1::from_handler_state(&parameters, &operation_state)
260 .await
261 .map_err(|e| OperationError::Internal(e.into()))?;
262 let a2 = A2::from_handler_state(&parameters, &operation_state)
263 .await
264 .map_err(|e| OperationError::Internal(e.into()))?;
265 let a3 = A3::from_handler_state(&parameters, &operation_state)
266 .await
267 .map_err(|e| OperationError::Internal(e.into()))?;
268
269 let (r1, r2) = parameters;
270 (self.clone())(r1, r2, state, operation_state, a1, a2, a3).await
271 }
272 }

giterated-stack/src/handler/mod.rs

View file
@@ -0,0 +1,239 @@
1 use std::{any::Any, sync::Arc};
2 pub mod handler_impl;
3 use futures_util::{future::LocalBoxFuture, Future, FutureExt};
4 use giterated_models::error::OperationError;
5
6 use crate::{
7 AuthenticatedInstance, AuthenticatedUser, GiteratedStack, MissingValue, StackOperationState,
8 };
9
10 #[async_trait::async_trait(?Send)]
11 pub trait IntoGiteratedHandler<Params, AdditionalParams, State, OState, Output>
12 where
13 // Output cannot have non-static references
14 Output: 'static,
15 {
16 type Future: Future<Output = Output>;
17
18 async fn handle(&self, parameters: Params, state: State, operation_state: OState) -> Output;
19 }
20
21 pub struct HandlerTree<Kind> {
22 elements: Vec<Kind>,
23 }
24
25 impl<Kind> Default for HandlerTree<Kind> {
26 fn default() -> Self {
27 Self {
28 elements: Default::default(),
29 }
30 }
31 }
32
33 impl<'fut: 'o + 'p, 'p, 'o, P, O, E> HandlerTree<HandlerWrapper<P, O, E>>
34 where
35 P: Clone,
36 {
37 pub fn push(&mut self, handler: HandlerWrapper<P, O, E>) {
38 self.elements.push(handler);
39 }
40 pub async fn handle(
41 &self,
42 parameters: P,
43 operation_state: StackOperationState,
44 ) -> Result<O, OperationError<E>> {
45 for handler in self.elements.iter() {
46 match handler
47 .handle(parameters.clone(), operation_state.clone())
48 .await
49 {
50 Ok(handled) => return Ok(handled),
51 Err(err) => match err {
52 OperationError::Internal(err) => return Err(OperationError::Internal(err)),
53 OperationError::Operation(err) => return Err(OperationError::Operation(err)),
54 OperationError::Unhandled => continue,
55 },
56 }
57 }
58
59 Err(OperationError::Unhandled)
60 }
61 }
62
63 pub struct HandlerWrapper<P, O, E> {
64 func: Arc<
65 dyn Fn(
66 P,
67 Arc<dyn Any + Send + Sync>,
68 StackOperationState,
69 ) -> LocalBoxFuture<'static, Result<O, OperationError<E>>>
70 + Send
71 + Sync,
72 >,
73 state: Arc<dyn Any + Send + Sync>,
74 }
75
76 impl<P, O, E> HandlerWrapper<P, O, E> {
77 pub fn new<S, F, A>(state: S, handler: F) -> Self
78 where
79 F: IntoGiteratedHandler<P, A, S, StackOperationState, Result<O, OperationError<E>>>
80 + Send
81 + Sync,
82 S: Send + Sync + Clone + 'static,
83 E: 'static,
84 P: 'static + Clone,
85 F: 'static,
86 O: 'static,
87 {
88 let state = Arc::new(state);
89
90 let handler_func = Arc::new(handler);
91 let state_two = state.clone();
92 HandlerWrapper {
93 func: Arc::new(
94 move |args: P,
95 state: Arc<dyn Any + Send + Sync>,
96 operation_state: StackOperationState| {
97 let handler = handler_func.clone();
98 let operation_state = operation_state.clone();
99 let state = state.downcast_ref::<S>().unwrap();
100 let state = state.clone();
101 async move {
102 let handler = handler.clone();
103 let operation_state = operation_state;
104 handler.handle(args, state, operation_state).await
105 }
106 .boxed_local()
107 },
108 ),
109 state: state_two,
110 }
111 }
112
113 pub async fn handle(
114 &self,
115 required: P,
116 operation_state: StackOperationState,
117 ) -> Result<O, OperationError<E>> {
118 (self.func)(required, self.state.clone(), operation_state).await
119 }
120
121 pub fn map<F, N, R>(self, predicate: F) -> HandlerWrapper<N, O, R>
122 where
123 F: Fn(&N, &StackOperationState) -> Result<P, OperationError<R>> + Clone + Send + Sync,
124 R: std::fmt::Debug + 'static,
125 E: Into<OperationError<R>> + 'static,
126 F: 'static,
127 N: 'static,
128 P: 'static,
129 O: 'static,
130 {
131 let func = Arc::new(self.func);
132 let predicate = Arc::new(predicate);
133 HandlerWrapper {
134 func: Arc::new(
135 move |args: N,
136 state: Arc<dyn Any + Send + Sync>,
137 operation_state: StackOperationState| {
138 let predicate_output = predicate(&args, &operation_state);
139 let func = func.clone();
140 let operation_state: StackOperationState = operation_state.clone();
141 async move {
142 let predicate_output = predicate_output?;
143 let operation_state = operation_state;
144 match (func)(predicate_output, state, operation_state).await {
145 Ok(success) => Ok(success),
146 Err(_) => todo!(),
147 }
148 }
149 .boxed_local()
150 },
151 ),
152 state: self.state,
153 }
154 }
155
156 pub fn map_return<F, NR, NE>(self, predicate: F) -> HandlerWrapper<P, NR, NE>
157 where
158 F: Fn(Result<O, OperationError<E>>, &StackOperationState) -> Result<NR, OperationError<NE>>
159 + Clone
160 + Send
161 + Sync,
162 O: 'static,
163 F: 'static,
164 E: 'static,
165 P: 'static,
166 {
167 let predicate = Arc::new(predicate);
168 let func = self.func;
169 HandlerWrapper {
170 func: Arc::new(
171 move |args: P,
172 state: Arc<dyn Any + Send + Sync>,
173 operation_state: StackOperationState| {
174 let clone = predicate.clone();
175 let func = func.clone();
176 let _statoperation_statee = operation_state.clone();
177
178 async move {
179 let func = func.clone();
180 let clone = clone;
181 let operation_state = operation_state;
182 clone(
183 (func)(args, state, operation_state.clone()).await,
184 &operation_state,
185 )
186 }
187 .boxed_local()
188 },
189 ),
190 state: self.state,
191 }
192 }
193 }
194
195 #[async_trait::async_trait(?Send)]
196 pub trait HandlerResolvable<RequiredParameters, OperationState>: Sized {
197 type Error;
198
199 async fn from_handler_state(
200 required_parameters: &RequiredParameters,
201 operation_state: &OperationState,
202 ) -> Result<Self, Self::Error>;
203 }
204
205 #[async_trait::async_trait(?Send)]
206 impl<R> HandlerResolvable<R, StackOperationState> for Arc<GiteratedStack> {
207 type Error = MissingValue;
208
209 async fn from_handler_state(
210 _required_parameters: &R,
211 operation_state: &StackOperationState,
212 ) -> Result<Self, Self::Error> {
213 Ok(operation_state.runtime.clone())
214 }
215 }
216
217 #[async_trait::async_trait(?Send)]
218 impl<R> HandlerResolvable<R, StackOperationState> for AuthenticatedUser {
219 type Error = MissingValue;
220
221 async fn from_handler_state(
222 _required_parameters: &R,
223 operation_state: &StackOperationState,
224 ) -> Result<Self, Self::Error> {
225 operation_state.user.clone().ok_or_else(|| MissingValue)
226 }
227 }
228
229 #[async_trait::async_trait(?Send)]
230 impl<R> HandlerResolvable<R, StackOperationState> for AuthenticatedInstance {
231 type Error = MissingValue;
232
233 async fn from_handler_state(
234 _required_parameters: &R,
235 operation_state: &StackOperationState,
236 ) -> Result<Self, Self::Error> {
237 operation_state.instance.clone().ok_or_else(|| MissingValue)
238 }
239 }

giterated-stack/src/lib.rs

View file
@@ -1,18 +1,22 @@
1 1 mod handler;
2 pub use handler::*;
2 3 mod meta;
3 pub mod provider;
4 pub use handler::{GiteratedStack, GiteratedStackState, *};
5 4 pub use meta::*;
5 pub mod provider;
6 mod stack;
7 pub use stack::*;
8 mod substack;
6 9 use serde::{de::DeserializeOwned, Deserialize, Serialize};
10 pub use stack::*;
11 pub use substack::*;
7 12 pub mod state;
8 13 pub mod update;
9 14
10 use std::{any::Any, convert::Infallible, future::Future, ops::Deref, pin::Pin, sync::Arc};
15 use std::{any::Any, convert::Infallible, ops::Deref, sync::Arc};
11 16
12 17 use core::fmt::Debug;
13 use futures_util::FutureExt;
14 18 use giterated_models::{
15 error::{ExtractorError, IntoInternalError, OperationError, UnauthorizedError},
19 error::{ExtractorError, UnauthorizedError},
16 20 instance::{
17 21 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
18 22 },
@@ -26,335 +30,52 @@ use giterated_models::{
26 30 };
27 31
28 32 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
29 struct ObjectOperationPair {
30 pub object_name: String,
31 pub operation_name: String,
33 pub struct ObjectOperationPair<'a> {
34 pub object_name: &'a str,
35 pub operation_name: &'a str,
32 36 }
33 37
34 impl ObjectOperationPair {
38 impl ObjectOperationPair<'static> {
35 39 #[allow(unused)]
36 40 pub fn from_types<O: GiteratedObject, D: GiteratedOperation<O>>() -> Self {
37 41 Self {
38 object_name: O::object_name().to_string(),
39 operation_name: D::operation_name().to_string(),
42 object_name: O::object_name(),
43 operation_name: D::operation_name(),
40 44 }
41 45 }
42 46 }
43 47
44 48 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
45 pub struct ObjectValuePair {
46 pub object_kind: String,
47 pub value_kind: String,
49 pub struct ObjectValuePair<'a> {
50 pub object_kind: &'a str,
51 pub value_kind: &'a str,
48 52 }
49 53
50 impl ObjectValuePair {
51 pub fn from_types<O: GiteratedObject, D: GiteratedObjectValue<Object = O>>() -> Self {
54 impl ObjectValuePair<'static> {
55 pub fn from_types<O: GiteratedObject, V: GiteratedObjectValue<Object = O>>() -> Self {
52 56 Self {
53 object_kind: O::object_name().to_string(),
54 value_kind: D::value_name().to_string(),
57 object_kind: O::object_name(),
58 value_kind: V::value_name(),
55 59 }
56 60 }
57 61 }
58 62
59 63 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
60 pub struct ObjectSettingPair {
61 pub object_kind: String,
62 pub setting_name: String,
64 pub struct ObjectSettingPair<'a> {
65 pub object_kind: &'a str,
66 pub setting_name: &'a str,
63 67 }
64 68
65 impl ObjectSettingPair {
69 impl ObjectSettingPair<'static> {
66 70 pub fn from_types<O: GiteratedObject, S: Setting>() -> Self {
67 71 Self {
68 object_kind: O::object_name().to_string(),
69 setting_name: S::name().to_string(),
72 object_kind: O::object_name(),
73 setting_name: S::name(),
70 74 }
71 75 }
72 76 }
73 77
74 78 #[async_trait::async_trait(?Send)]
75 pub trait GiteratedOperationHandler<
76 L,
77 O: GiteratedObject,
78 D: GiteratedOperation<O>,
79 S: Send + Sync + Clone,
80 >
81 {
82 fn operation_name(&self) -> &str;
83 fn object_name(&self) -> &str;
84
85 async fn handle(
86 &self,
87 object: &O,
88 operation: D,
89 state: S,
90 operation_state: &StackOperationState,
91 ) -> Result<D::Success, OperationError<D::Failure>>;
92 }
93
94 #[async_trait::async_trait(?Send)]
95 impl<O, D, F, S> GiteratedOperationHandler<(), O, D, S> for F
96 where
97 F: FnMut(
98 &O,
99 D,
100 S,
101 )
102 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
103 + Send
104 + Sync
105 + Clone,
106 O: GiteratedObject + Send + Sync,
107 D: GiteratedOperation<O> + 'static,
108 <D as GiteratedOperation<O>>::Failure: Send,
109 S: Send + Sync + Clone + 'static,
110 {
111 fn operation_name(&self) -> &str {
112 D::operation_name()
113 }
114
115 fn object_name(&self) -> &str {
116 O::object_name()
117 }
118
119 async fn handle(
120 &self,
121 object: &O,
122 operation: D,
123 state: S,
124 _operation_state: &StackOperationState,
125 ) -> Result<D::Success, OperationError<D::Failure>> {
126 self.clone()(object, operation, state).await
127 }
128 }
129
130 #[async_trait::async_trait(?Send)]
131 impl<O, O1, D, F, S> GiteratedOperationHandler<(O1,), O, D, S> for F
132 where
133 F: FnMut(
134 &O,
135 D,
136 S,
137 O1,
138 )
139 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
140 + Send
141 + Sync
142 + Clone,
143 O: GiteratedObject + Send + Sync,
144 D: GiteratedOperation<O> + 'static + Send + Sync,
145 <D as GiteratedOperation<O>>::Failure: Send,
146 S: Send + Sync + Clone + 'static,
147 O1: FromOperationState<O, D>,
148 ExtractorError<<O1 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
149 {
150 fn operation_name(&self) -> &str {
151 D::operation_name()
152 }
153
154 fn object_name(&self) -> &str {
155 O::object_name()
156 }
157
158 async fn handle(
159 &self,
160 object: &O,
161 operation: D,
162 state: S,
163 operation_state: &StackOperationState,
164 ) -> Result<D::Success, OperationError<D::Failure>> {
165 let o1 = O1::from_state(object, &operation, operation_state)
166 .await
167 .as_internal_error()?;
168 self.clone()(object, operation, state, o1).await
169 }
170 }
171
172 #[async_trait::async_trait(?Send)]
173 impl<O, O1, O2, D, F, S> GiteratedOperationHandler<(O1, O2), O, D, S> for F
174 where
175 F: FnMut(
176 &O,
177 D,
178 S,
179 O1,
180 O2,
181 )
182 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
183 + Send
184 + Sync
185 + Clone,
186 O: GiteratedObject + Send + Sync,
187 D: GiteratedOperation<O> + 'static + Send + Sync,
188 <D as GiteratedOperation<O>>::Failure: Send,
189 S: Send + Sync + Clone + 'static,
190 O1: FromOperationState<O, D>,
191 ExtractorError<<O1 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
192 O2: FromOperationState<O, D>,
193 ExtractorError<<O2 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
194 {
195 fn operation_name(&self) -> &str {
196 D::operation_name()
197 }
198
199 fn object_name(&self) -> &str {
200 O::object_name()
201 }
202
203 async fn handle(
204 &self,
205 object: &O,
206 operation: D,
207 state: S,
208 operation_state: &StackOperationState,
209 ) -> Result<D::Success, OperationError<D::Failure>> {
210 let o1 = O1::from_state(object, &operation, operation_state)
211 .await
212 .as_internal_error()?;
213 let o2 = O2::from_state(object, &operation, operation_state)
214 .await
215 .as_internal_error()?;
216 self.clone()(object, operation, state, o1, o2).await
217 }
218 }
219
220 #[async_trait::async_trait(?Send)]
221 impl<O, O1, O2, O3, D, F, S> GiteratedOperationHandler<(O1, O2, O3), O, D, S> for F
222 where
223 F: FnMut(
224 &O,
225 D,
226 S,
227 O1,
228 O2,
229 O3,
230 )
231 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
232 + Send
233 + Sync
234 + Clone,
235 O: GiteratedObject + Send + Sync,
236 D: GiteratedOperation<O> + 'static + Send + Sync,
237 <D as GiteratedOperation<O>>::Failure: Send,
238 S: Send + Sync + Clone + 'static,
239 O1: FromOperationState<O, D>,
240 ExtractorError<<O1 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
241 O2: FromOperationState<O, D>,
242 ExtractorError<<O2 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
243 O3: FromOperationState<O, D>,
244 ExtractorError<<O3 as FromOperationState<O, D>>::Error>: Into<anyhow::Error>,
245 {
246 fn operation_name(&self) -> &str {
247 D::operation_name()
248 }
249
250 fn object_name(&self) -> &str {
251 O::object_name()
252 }
253
254 async fn handle(
255 &self,
256 object: &O,
257 operation: D,
258 state: S,
259 operation_state: &StackOperationState,
260 ) -> Result<D::Success, OperationError<D::Failure>> {
261 let o1 = O1::from_state(object, &operation, operation_state)
262 .await
263 .as_internal_error()?;
264 let o2 = O2::from_state(object, &operation, operation_state)
265 .await
266 .as_internal_error()?;
267 let o3 = O3::from_state(object, &operation, operation_state)
268 .await
269 .as_internal_error()?;
270 self.clone()(object, operation, state, o1, o2, o3).await
271 }
272 }
273
274 pub struct OperationWrapper {
275 func: Box<
276 dyn Fn(
277 &(dyn Any + Send + Sync),
278 &(dyn Any + Send + Sync),
279 &(dyn Any + Send + Sync),
280 StackOperationState,
281 ) -> Pin<
282 Box<
283 dyn Future<
284 Output = Result<
285 Box<dyn Any + Send + Sync>,
286 OperationError<Box<dyn Any + Send + Sync>>,
287 >,
288 >,
289 >,
290 > + Send
291 + Sync,
292 >,
293 state: Box<dyn Any + Send + Sync>,
294 }
295
296 impl OperationWrapper {
297 pub fn new<
298 A,
299 O: GiteratedObject + Send + Sync + 'static,
300 D: GiteratedOperation<O> + 'static + Clone,
301 F: GiteratedOperationHandler<A, O, D, S> + 'static + Send + Sync + Clone,
302 S: GiteratedStackState + 'static,
303 >(
304 handler: F,
305 state: S,
306 ) -> Self
307 where
308 D::Failure: Send + Sync,
309 D::Success: Send + Sync,
310 {
311 Self {
312 func: Box::new(move |object, operation, state, operation_state| {
313 let handler = handler.clone();
314 let state = state.downcast_ref::<S>().unwrap().clone();
315 let object: &O = object.downcast_ref().unwrap();
316 let operation: &D = operation.downcast_ref().unwrap();
317 let object = object.clone();
318 let operation = operation.clone();
319 async move {
320 let result = handler
321 .handle(&object, operation, state, &operation_state)
322 .await;
323 result
324 .map(|success| Box::new(success) as _)
325 .map_err(|err| match err {
326 OperationError::Operation(err) => {
327 OperationError::Operation(Box::new(err) as _)
328 }
329 OperationError::Internal(internal) => {
330 OperationError::Internal(internal)
331 }
332 OperationError::Unhandled => OperationError::Unhandled,
333 })
334 }
335 .boxed_local()
336 }),
337 state: Box::new(state),
338 }
339 }
340
341 async fn handle(
342 &self,
343 object: &Box<dyn Any + Send + Sync>,
344 operation: &Box<dyn Any + Send + Sync>,
345 operation_state: &StackOperationState,
346 ) -> Result<Box<dyn Any + Send + Sync>, OperationError<Box<dyn Any + Send + Sync>>> {
347 (self.func)(
348 (*object).as_ref(),
349 (*operation).as_ref(),
350 self.state.as_ref(),
351 operation_state.clone(),
352 )
353 .await
354 }
355 }
356
357 #[async_trait::async_trait(?Send)]
358 79 pub trait FromOperationState<O: GiteratedObject, D: GiteratedOperation<O>>: Sized + Clone {
359 80 type Error: Into<anyhow::Error>;
360 81
@@ -367,21 +88,6 @@ pub trait FromOperationState<O: GiteratedObject, D: GiteratedOperation<O>>: Size
367 88
368 89 #[async_trait::async_trait(?Send)]
369 90 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
370 for Arc<GiteratedStack>
371 {
372 type Error = Infallible;
373
374 async fn from_state(
375 _object: &O,
376 _operation: &D,
377 state: &StackOperationState,
378 ) -> Result<Self, ExtractorError<Infallible>> {
379 Ok(state.runtime.clone())
380 }
381 }
382
383 #[async_trait::async_trait(?Send)]
384 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
385 91 for StackOperationState
386 92 {
387 93 type Error = Infallible;
@@ -688,15 +394,6 @@ impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance
688 394 }
689 395 }
690 396
691 // #[async_trait::async_trait> FromOperationState for Option<T> {
692 // type Error = ();
693
694 // async fn from_state(state: &StackOperationState) -> Result<Option<T>, OperationError<()>> {
695 // Ok(T::from_state(]
696 // impl<T: FromOperationStatestate).await.ok())
697 // }
698 // }
699
700 397 #[derive(Clone)]
701 398 pub struct StackOperationState {
702 399 pub our_instance: Instance,
@@ -753,3 +450,21 @@ where
753 450
754 451 type Failure = ();
755 452 }
453
454 #[derive(Clone)]
455 pub struct AnyObject(pub Arc<dyn Any + Send + Sync>);
456
457 #[derive(Clone)]
458 pub struct AnyOperation(pub Arc<dyn Any + Send>);
459
460 #[derive(Clone)]
461 pub struct AnySuccess(pub Arc<dyn Any + Send>);
462
463 #[derive(Clone)]
464 pub struct AnyFailure(pub Arc<dyn Any + Send>);
465
466 #[derive(Clone)]
467 pub struct AnyValue(pub Arc<dyn Any + Send>);
468
469 #[derive(Clone)]
470 pub struct AnySetting(pub Arc<dyn Any + Send + Sync>);

giterated-stack/src/meta/mod.rs

View file
@@ -1,4 +1,4 @@
1 use std::{any::Any, str::FromStr, sync::Arc};
1 use std::{any::Any, collections::HashMap, str::FromStr, sync::Arc};
2 2
3 3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 4 use giterated_models::{
@@ -8,23 +8,134 @@ use giterated_models::{
8 8 value::{GetValueTyped, GiteratedObjectValue},
9 9 };
10 10 use serde_json::Value;
11 use tracing::trace;
11 12
12 use crate::{GiteratedStack, StackOperationState};
13 use crate::{
14 AnyFailure, AnyObject, AnyOperation, AnySetting, AnySuccess, AnyValue, GiteratedStack,
15 ObjectOperationPair, ObjectSettingPair, ObjectValuePair, StackOperationState,
16 };
17
18 /// Stores runtime metadata for all in-use Giterated protocol types.
19 #[derive(Default)]
20 pub struct RuntimeMetadata {
21 pub objects: HashMap<String, ObjectMeta>,
22 pub operations: HashMap<ObjectOperationPair<'static>, OperationMeta>,
23 pub values: HashMap<ObjectValuePair<'static>, ValueMeta>,
24 pub settings: HashMap<ObjectSettingPair<'static>, SettingMeta>,
25 }
26
27 impl RuntimeMetadata {
28 pub fn register_object<O: GiteratedObject + 'static>(&mut self) {
29 let object_name = O::object_name().to_string();
30
31 let object_meta = ObjectMeta::new::<O>();
32
33 if self.objects.insert(object_name, object_meta).is_some() {
34 trace!(
35 "Registration of object {} overwrote previous registration.",
36 O::object_name()
37 );
38 } else {
39 trace!("Registration of object {}.", O::object_name())
40 }
41 }
42
43 pub fn register_operation<O: GiteratedObject + 'static, D: GiteratedOperation<O> + 'static>(
44 &mut self,
45 ) {
46 let _object_name = O::object_name().to_string();
47 let _operation_name = D::operation_name().to_string();
48
49 if self
50 .operations
51 .insert(
52 ObjectOperationPair::from_types::<O, D>(),
53 OperationMeta::new::<O, D>(),
54 )
55 .is_some()
56 {
57 trace!(
58 "Registration of object operation {}<{}> overwrote previous registration.",
59 D::operation_name(),
60 O::object_name()
61 );
62 } else {
63 trace!(
64 "Registration of object operation {}<{}>.",
65 D::operation_name(),
66 O::object_name()
67 )
68 }
69 }
70
71 pub fn register_value<
72 O: GiteratedObject + 'static,
73 V: GiteratedObjectValue<Object = O> + 'static,
74 >(
75 &mut self,
76 ) {
77 let _object_name = O::object_name().to_string();
78 let _value_name = V::value_name().to_string();
79
80 if self
81 .values
82 .insert(ObjectValuePair::from_types::<O, V>(), ValueMeta::new::<V>())
83 .is_some()
84 {
85 trace!(
86 "Registration of value <{}>::{} overwrote previous registration.",
87 O::object_name(),
88 V::value_name()
89 );
90 } else {
91 trace!(
92 "Registration of value <{}>::{}.",
93 O::object_name(),
94 V::value_name()
95 );
96 }
97 }
98
99 pub fn register_setting<O: GiteratedObject + 'static, S: Setting + 'static + Clone>(&mut self) {
100 if self
101 .settings
102 .insert(
103 ObjectSettingPair::from_types::<O, S>(),
104 SettingMeta::new::<O, S>(),
105 )
106 .is_some()
107 {
108 trace!(
109 "Registration of setting {} overwrote previous registration.",
110 S::name()
111 );
112 } else {
113 trace!("Registration of setting {}.", S::name());
114 }
115 }
116
117 pub fn append(&mut self, other: Self) {
118 self.objects.extend(other.objects);
119 self.operations.extend(other.operations);
120 self.values.extend(other.values);
121 self.settings.extend(other.settings);
122 }
123 }
13 124
14 125 pub struct ValueMeta {
15 126 pub name: String,
16 pub deserialize: fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error>,
17 pub serialize: fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error>,
127 pub deserialize: fn(&[u8]) -> Result<AnyValue, serde_json::Error>,
128 pub serialize: fn(AnyValue) -> Result<Vec<u8>, serde_json::Error>,
18 129 pub typed_get: fn() -> Box<dyn Any + Send + Sync>,
19 pub is_get_value_typed: fn(&Box<dyn Any + Send + Sync>) -> bool,
130 pub is_get_value_typed: fn(AnyOperation) -> bool,
20 131 }
21 132
22 133 pub trait IntoValueMeta {
23 134 fn name() -> String;
24 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error>;
25 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error>;
135 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error>;
136 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error>;
26 137 fn typed_get() -> Box<dyn Any + Send + Sync>;
27 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool;
138 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool;
28 139 }
29 140
30 141 impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValueMeta for V {
@@ -32,25 +143,24 @@ impl<O: GiteratedObject, V: GiteratedObjectValue<Object = O> + 'static> IntoValu
32 143 V::value_name().to_string()
33 144 }
34 145
35 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any>, serde_json::Error> {
36 Ok(Box::new(serde_json::from_slice(buffer)?))
146 fn deserialize(buffer: &[u8]) -> Result<AnyValue, serde_json::Error> {
147 Ok(AnyValue(Arc::new(serde_json::from_slice(buffer)?)))
37 148 }
38 149
39 fn serialize(value: Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> {
40 let value = value.downcast::<V>().unwrap();
150 fn serialize(value: AnyValue) -> Result<Vec<u8>, serde_json::Error> {
151 let value = value.0.downcast_ref::<V>().unwrap();
41 152
42 153 serde_json::to_vec(&*value)
43 154 }
44 155
45 156 fn typed_get() -> Box<dyn Any + Send + Sync> {
46 157 Box::new(GetValueTyped::<V> {
47 value_name: V::value_name().to_string(),
48 158 ty: Default::default(),
49 159 })
50 160 }
51 161
52 fn is_get_value_typed(typed_get_value: &Box<dyn Any + Send + Sync>) -> bool {
53 typed_get_value.is::<GetValueTyped<V>>()
162 fn is_get_value_typed(typed_get_value: AnyOperation) -> bool {
163 typed_get_value.0.is::<GetValueTyped<V>>()
54 164 }
55 165 }
56 166
@@ -69,17 +179,17 @@ impl ValueMeta {
69 179 pub struct OperationMeta {
70 180 pub name: String,
71 181 pub object_kind: String,
72 pub deserialize: fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>,
182 pub deserialize: fn(&[u8]) -> Result<AnyOperation, serde_json::Error>,
73 183 pub any_is_same: fn(&dyn Any) -> bool,
74 pub serialize_success: fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>,
75 pub serialize_error: fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>,
184 pub serialize_success: fn(AnySuccess) -> Result<Vec<u8>, serde_json::Error>,
185 pub serialize_error: fn(AnyFailure) -> Result<Vec<u8>, serde_json::Error>,
76 186 }
77 187
78 188 pub trait IntoOperationMeta<O> {
79 189 fn name() -> String;
80 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>;
81 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
82 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error>;
190 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error>;
191 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error>;
192 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error>;
83 193 fn any_is_same(other: &dyn Any) -> bool;
84 194 }
85 195
@@ -94,17 +204,19 @@ where
94 204 D::operation_name().to_string()
95 205 }
96 206
97 fn deserialize(buffer: &[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> {
98 Ok(Box::new(serde_json::from_slice::<D>(buffer)?) as Box<dyn Any + Send + Sync>)
207 fn deserialize(buffer: &[u8]) -> Result<AnyOperation, serde_json::Error> {
208 Ok(AnyOperation(
209 Arc::new(serde_json::from_slice::<D>(buffer)?) as Arc<dyn Any + Send + Sync>
210 ))
99 211 }
100 212
101 fn serialize_success(success: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
102 let to_serialize = success.downcast::<D::Success>().unwrap();
213 fn serialize_success(success: AnySuccess) -> Result<Vec<u8>, serde_json::Error> {
214 let to_serialize = success.0.downcast_ref::<D::Success>().unwrap();
103 215 serde_json::to_vec(&to_serialize)
104 216 }
105 217
106 fn serialize_failure(failure: Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> {
107 let to_serialize = failure.downcast::<D::Failure>().unwrap();
218 fn serialize_failure(failure: AnyFailure) -> Result<Vec<u8>, serde_json::Error> {
219 let to_serialize = failure.0.downcast_ref::<D::Failure>().unwrap();
108 220 serde_json::to_vec(&to_serialize)
109 221 }
110 222
@@ -128,7 +240,7 @@ impl OperationMeta {
128 240
129 241 pub struct ObjectMeta {
130 242 pub name: String,
131 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
243 pub from_str: Box<dyn Fn(&str) -> Result<AnyObject, ()> + Send + Sync>,
132 244 pub any_is_same: fn(&dyn Any) -> bool,
133 245 }
134 246
@@ -154,7 +266,7 @@ impl ObjectMeta {
154 266 from_str: Box::new(|source| {
155 267 let object = I::from_str(source).map_err(|_| ())?;
156 268
157 Ok(Box::new(object) as Box<dyn Any + Send + Sync>)
269 Ok(AnyObject(Arc::new(object) as Arc<dyn Any + Send + Sync>))
158 270 }),
159 271 any_is_same: I::any_is_same,
160 272 }
@@ -163,11 +275,11 @@ impl ObjectMeta {
163 275
164 276 pub struct SettingMeta {
165 277 pub name: String,
166 pub deserialize: fn(Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>,
167 pub serialize: fn(&(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error>,
278 pub deserialize: fn(Value) -> Result<AnySetting, serde_json::Error>,
279 pub serialize: fn(AnySetting) -> Result<Value, serde_json::Error>,
168 280 pub setting_updated: for<'fut> fn(
169 Box<dyn Any + Send + Sync>,
170 Box<dyn Any + Send + Sync>,
281 AnyObject,
282 AnySetting,
171 283 Arc<GiteratedStack>,
172 284 &StackOperationState,
173 285 ) -> LocalBoxFuture<'_, ()>,
@@ -175,40 +287,40 @@ pub struct SettingMeta {
175 287
176 288 pub trait IntoSettingMeta<O> {
177 289 fn name() -> String;
178 fn deserialize(value: Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error>;
179 fn serialize(setting: &(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error>;
290 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error>;
291 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error>;
180 292 fn setting_updated(
181 object: Box<dyn Any + Send + Sync>,
182 setting: Box<dyn Any + Send + Sync>,
293 object: AnyObject,
294 setting: AnySetting,
183 295 stack: Arc<GiteratedStack>,
184 296 operation_state: &StackOperationState,
185 297 ) -> LocalBoxFuture<'_, ()>;
186 298 }
187 299
188 impl<O: GiteratedObject + 'static, S: Setting + 'static> IntoSettingMeta<O> for S {
300 impl<O: GiteratedObject + 'static, S: Setting + 'static + Clone> IntoSettingMeta<O> for S {
189 301 fn name() -> String {
190 302 S::name().to_string()
191 303 }
192 304
193 fn deserialize(value: Value) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> {
194 Ok(Box::new(serde_json::from_value::<S>(value)?))
305 fn deserialize(value: Value) -> Result<AnySetting, serde_json::Error> {
306 Ok(AnySetting(Arc::new(serde_json::from_value::<S>(value)?)))
195 307 }
196 308
197 fn serialize(setting: &(dyn Any + Send + Sync)) -> Result<Value, serde_json::Error> {
198 serde_json::to_value(setting.downcast_ref::<S>().unwrap())
309 fn serialize(setting: AnySetting) -> Result<Value, serde_json::Error> {
310 serde_json::to_value(setting.0.downcast_ref::<S>().unwrap())
199 311 }
200 312
201 313 fn setting_updated(
202 object: Box<dyn Any + Send + Sync>,
203 setting: Box<dyn Any + Send + Sync>,
314 object: AnyObject,
315 setting: AnySetting,
204 316 stack: Arc<GiteratedStack>,
205 317 operation_state: &StackOperationState,
206 318 ) -> LocalBoxFuture<'_, ()> {
207 319 async move {
208 320 stack
209 321 .setting_update(
210 *object.downcast::<O>().unwrap(),
211 *setting.downcast::<S>().unwrap(),
322 object.0.downcast_ref::<O>().unwrap().clone(),
323 setting.0.downcast_ref::<S>().unwrap().clone(),
212 324 operation_state,
213 325 )
214 326 .await

giterated-stack/src/provider/metadata.rs

View file
@@ -4,21 +4,21 @@ use anyhow::Error;
4 4
5 5 use serde_json::Value;
6 6
7 use crate::{ObjectMeta, SettingMeta};
7 use crate::{AnyObject, AnySetting, ObjectMeta, SettingMeta};
8 8
9 9 #[async_trait::async_trait]
10 10 pub trait MetadataProvider: Send + Sync + 'static {
11 11 fn provides_for(&self, object: &dyn Any) -> bool;
12 12 async fn write(
13 13 &self,
14 object: &(dyn Any + Send + Sync),
14 object: AnyObject,
15 15 object_meta: &ObjectMeta,
16 setting: &(dyn Any + Send + Sync),
16 setting: AnySetting,
17 17 setting_meta: &SettingMeta,
18 18 ) -> Result<(), Error>;
19 19 async fn read(
20 20 &self,
21 object: &(dyn Any + Send + Sync),
21 object: AnyObject,
22 22 object_meta: &ObjectMeta,
23 23 setting_meta: &SettingMeta,
24 24 ) -> Result<Value, Error>;

giterated-stack/src/stack.rs

View file
@@ -0,0 +1,865 @@
1 use std::any::Any;
2
3 use std::fmt::Debug;
4 use std::{collections::HashMap, sync::Arc};
5
6 use giterated_models::authenticated::AuthenticatedPayload;
7 use giterated_models::error::{GetValueError, IntoInternalError};
8 use giterated_models::message::GiteratedMessage;
9 use giterated_models::object::NetworkAnyObject;
10 use giterated_models::operation::NetworkAnyOperation;
11 use giterated_models::settings::{GetSettingError, Setting};
12 use giterated_models::value::{GetValue, GiteratedObjectValue};
13 use giterated_models::{
14 error::OperationError,
15 object::{GiteratedObject, Object, ObjectRequest, ObjectRequestError},
16 object_backend::ObjectBackend,
17 operation::GiteratedOperation,
18 settings::{GetSetting, SetSetting},
19 };
20 use tracing::trace;
21
22 use crate::handler::HandlerTree;
23 use crate::provider::MetadataProvider;
24 use crate::{
25 AnyFailure, AnyObject, AnyOperation, AnySetting, AnySuccess, AnyValue, HandlerResolvable,
26 HandlerWrapper, MissingValue, ObjectOperationPair, ObjectSettingPair, ObjectValuePair,
27 RuntimeMetadata, StackOperationState, SubstackBuilder,
28 };
29
30 pub type OperationHandler = HandlerWrapper<(AnyObject, AnyOperation), AnySuccess, AnyFailure>;
31
32 pub type ValueGetter = HandlerWrapper<(AnyObject,), AnyValue, AnyFailure>;
33
34 pub type SettingGetter = HandlerWrapper<(AnyObject,), AnySetting, AnyFailure>;
35
36 pub type ValueChange = HandlerWrapper<(AnyObject, AnyValue), (), anyhow::Error>;
37
38 pub type SettingChange = HandlerWrapper<(AnyObject, AnySetting), (), anyhow::Error>;
39
40 #[derive(Default)]
41 pub struct GiteratedStack {
42 operation_handlers: HashMap<ObjectOperationPair<'static>, HandlerTree<OperationHandler>>,
43 value_getters: HashMap<ObjectValuePair<'static>, ValueGetter>,
44 setting_getters: HashMap<&'static str, SettingGetter>,
45 value_change: HashMap<ObjectValuePair<'static>, ValueChange>,
46 setting_change: HashMap<ObjectSettingPair<'static>, SettingChange>,
47 metadata_providers: Vec<Box<dyn MetadataProvider>>,
48 pub metadata: RuntimeMetadata,
49 }
50
51 impl Debug for GiteratedStack {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 f.debug_struct("GiteratedStack").finish()
54 }
55 }
56
57 impl GiteratedStack {
58 pub fn merge_builder<S: GiteratedStackState>(
59 &mut self,
60 mut builder: SubstackBuilder<S>,
61 ) -> &mut Self {
62 for (target, handler) in builder.operation_handlers {
63 let tree = self.get_or_create_tree(&target);
64
65 tree.push(handler);
66 }
67
68 for (target, handler) in builder.value_getters {
69 assert!(self.value_getters.insert(target, handler).is_none());
70 }
71
72 for (target, handler) in builder.setting_getters {
73 assert!(self.setting_getters.insert(target, handler).is_none());
74 }
75
76 for (target, handler) in builder.value_change {
77 self.value_change.insert(target, handler);
78 }
79
80 for (target, handler) in builder.setting_change {
81 self.setting_change.insert(target, handler);
82 }
83
84 self.metadata_providers
85 .append(&mut builder.metadata_providers);
86
87 self.metadata.append(builder.metadata);
88
89 self
90 }
91
92 pub async fn value_update<O, V>(
93 &self,
94 object: O,
95 new_value: V,
96 operation_state: &StackOperationState,
97 ) where
98 O: GiteratedObject + 'static,
99 V: GiteratedObjectValue<Object = O> + 'static,
100 {
101 trace!("value updated {}::{}", O::object_name(), V::value_name());
102 let target = ObjectValuePair::from_types::<O, V>();
103
104 if let Some(handler) = self.value_change.get(&target) {
105 // TODO
106 let _ = handler
107 .handle(
108 (AnyObject(Arc::new(object)), AnyValue(Arc::new(new_value))),
109 operation_state.clone(),
110 )
111 .await;
112 }
113 }
114
115 pub async fn setting_update<O, S>(
116 &self,
117 object: O,
118 new_setting: S,
119 operation_state: &StackOperationState,
120 ) where
121 O: GiteratedObject + 'static,
122 S: Setting + 'static,
123 {
124 trace!("setting updated {}::{}", O::object_name(), S::name());
125 let target = ObjectSettingPair::from_types::<O, S>();
126
127 if let Some(handler) = self.setting_change.get(&target) {
128 let _ = handler
129 .handle(
130 (
131 AnyObject(Arc::new(object)),
132 AnySetting(Arc::new(new_setting)),
133 ),
134 operation_state.clone(),
135 )
136 .await;
137 }
138 }
139
140 pub async fn new_object<O>(&self, _new_object: &O, _operation_state: &StackOperationState)
141 where
142 O: GiteratedObject,
143 {
144 // TODO
145 }
146
147 /// Writes a setting for the specified object.
148 pub async fn write_setting<O, S>(
149 &self,
150 object: &O,
151 setting: S,
152 ) -> Result<(), OperationError<()>>
153 where
154 O: GiteratedObject + 'static + Clone,
155 S: Setting + 'static + Clone,
156 {
157 for provider in self.metadata_providers.iter() {
158 if provider.provides_for(object as &dyn Any) {
159 let setting_meta = self
160 .metadata
161 .settings
162 .get(&ObjectSettingPair::from_types::<O, S>())
163 .ok_or_else(|| OperationError::Unhandled)?;
164
165 let object_meta = self
166 .metadata
167 .objects
168 .get(O::object_name())
169 .ok_or_else(|| OperationError::Unhandled)?;
170
171 let result = provider
172 .write(
173 AnyObject(Arc::new(object.clone())),
174 object_meta,
175 AnySetting(Arc::new(setting)),
176 setting_meta,
177 )
178 .await
179 .as_internal_error_with_context(format!("writing setting {}", S::name()));
180
181 return result;
182 }
183 }
184
185 Err(OperationError::Unhandled)
186 }
187
188 /// Gets a setting for the specified object.
189 pub async fn new_get_setting<O, S>(&self, object: &O) -> Result<S, OperationError<MissingValue>>
190 where
191 O: GiteratedObject + 'static + Clone,
192 S: Setting + 'static,
193 {
194 for provider in self.metadata_providers.iter() {
195 if provider.provides_for(object as &dyn Any) {
196 trace!(
197 "Resolving setting {} for object {} from provider.",
198 S::name(),
199 O::object_name()
200 );
201
202 let setting_meta = self
203 .metadata
204 .settings
205 .get(&ObjectSettingPair::from_types::<O, S>())
206 .ok_or_else(|| OperationError::Unhandled)?;
207
208 let object_meta = self
209 .metadata
210 .objects
211 .get(O::object_name())
212 .ok_or_else(|| OperationError::Unhandled)?;
213
214 let value = provider
215 .read(
216 AnyObject(Arc::new(object.clone())),
217 object_meta,
218 setting_meta,
219 )
220 .await
221 .as_internal_error_with_context(format!("getting setting {}", S::name()))?;
222
223 return serde_json::from_value(value)
224 .as_internal_error_with_context("deserializing setting");
225 }
226 }
227 trace!(
228 "No provider registered for setting {} and object {}",
229 S::name(),
230 O::object_name()
231 );
232
233 Err(OperationError::Unhandled)
234 }
235
236 fn get_or_create_tree(
237 &mut self,
238 target: &ObjectOperationPair<'static>,
239 ) -> &mut HandlerTree<OperationHandler> {
240 if self.operation_handlers.contains_key(target) {
241 self.operation_handlers.get_mut(target).unwrap()
242 } else {
243 self.operation_handlers
244 .insert(target.clone(), HandlerTree::default());
245
246 self.operation_handlers.get_mut(target).unwrap()
247 }
248 }
249 }
250
251 impl GiteratedStack {
252 /// Handles a giterated network message, returning either a raw success
253 /// payload or a serialized error payload.
254 pub async fn handle_network_message(
255 &self,
256 message: AuthenticatedPayload,
257 operation_state: &StackOperationState,
258 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
259 let message: GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> =
260 message.into_message();
261
262 // Deserialize the object, also getting the object type's name
263 let (object_type, object) = {
264 let mut result = None;
265
266 for (object_type, object_meta) in self.metadata.objects.iter() {
267 if let Ok(object) = (object_meta.from_str)(&message.object.0) {
268 result = Some((object_type.clone(), object));
269 break;
270 }
271 }
272
273 result
274 }
275 .ok_or_else(|| OperationError::Unhandled)?;
276
277 trace!(
278 "Handling network message {}::<{}>",
279 message.operation,
280 object_type
281 );
282
283 if message.operation == "get_value" {
284 // Special case
285 let operation: GetValue = serde_json::from_slice(&message.payload.0).unwrap();
286
287 let result = self
288 .network_get_value(
289 object,
290 object_type.clone(),
291 operation.clone(),
292 operation_state,
293 )
294 .await;
295
296 // In the case of internal errors, attach context
297 let result = result.map_err(|err| match err {
298 OperationError::Operation(operation) => OperationError::Operation(operation),
299 OperationError::Internal(internal) => {
300 OperationError::Internal(internal.context(format!(
301 "{}::get_value::<{}> outcome",
302 object_type, operation.value_name
303 )))
304 }
305 OperationError::Unhandled => OperationError::Unhandled,
306 });
307
308 return result;
309 } else if message.operation == "get_setting" {
310 let operation: GetSetting = serde_json::from_slice(&message.payload.0).unwrap();
311 let setting_meta = self
312 .metadata
313 .settings
314 .get(&ObjectSettingPair {
315 object_kind: &object_type,
316 setting_name: &operation.setting_name,
317 })
318 .ok_or_else(|| OperationError::Unhandled)?;
319 let raw_result = self
320 .get_setting(
321 object,
322 object_type.clone(),
323 operation.clone(),
324 operation_state,
325 )
326 .await;
327 return match raw_result {
328 Ok(success) => {
329 // Success is the setting type, serialize it
330 let serialized = (setting_meta.serialize)(success).unwrap();
331
332 Ok(serde_json::to_vec(&serialized).unwrap())
333 }
334 Err(err) => Err(match err {
335 OperationError::Operation(failure) => {
336 // We know how to resolve this type
337 let failure: GetSettingError = *failure.downcast().unwrap();
338
339 OperationError::Operation(serde_json::to_vec(&failure).unwrap())
340 }
341 OperationError::Internal(internal) => {
342 OperationError::Internal(internal.context(format!(
343 "{}::get_setting::<{}> handler outcome",
344 object_type, setting_meta.name
345 )))
346 }
347 OperationError::Unhandled => OperationError::Unhandled,
348 }),
349 };
350 } else if message.operation == "set_setting" {
351 let operation: SetSetting = serde_json::from_slice(&message.payload.0).unwrap();
352
353 trace!(
354 "Handling network {}::set_setting for {}",
355 object_type,
356 operation.setting_name
357 );
358
359 let setting_meta = self
360 .metadata
361 .settings
362 .get(&ObjectSettingPair {
363 object_kind: &object_type,
364 setting_name: &operation.setting_name,
365 })
366 .unwrap();
367
368 let setting = (setting_meta.deserialize)(operation.value)
369 .as_internal_error_with_context(format!(
370 "deserializing setting {} for object {}",
371 operation.setting_name, object_type
372 ))?;
373
374 trace!(
375 "Deserialized setting {} for object {}",
376 operation.setting_name,
377 object_type,
378 );
379
380 for provider in self.metadata_providers.iter() {
381 if provider.provides_for(object.0.as_ref()) {
382 trace!(
383 "Resolved setting provider for setting {} for object {}",
384 operation.setting_name,
385 object_type,
386 );
387
388 let object_meta = self
389 .metadata
390 .objects
391 .get(&object_type)
392 .ok_or_else(|| OperationError::Unhandled)?;
393
394 let raw_result = provider
395 .write(object.clone(), object_meta, setting.clone(), setting_meta)
396 .await;
397
398 return match raw_result {
399 Ok(_) => {
400 (setting_meta.setting_updated)(
401 object,
402 setting,
403 operation_state.runtime.clone(),
404 operation_state,
405 )
406 .await;
407
408 Ok(serde_json::to_vec(&()).unwrap())
409 }
410 Err(e) => Err(OperationError::Internal(e.context(format!(
411 "writing object {} setting {}",
412 object_type, operation.setting_name
413 )))),
414 };
415 }
416
417 trace!(
418 "Failed to resolve setting provider for setting {} for object {}",
419 operation.setting_name,
420 object_type,
421 );
422 }
423 }
424
425 let target = ObjectOperationPair {
426 object_name: &object_type,
427 operation_name: &message.operation,
428 };
429
430 // Resolve the target operations from the handlers table
431 let handler = self
432 .operation_handlers
433 .get(&target)
434 .ok_or_else(|| OperationError::Unhandled)?;
435
436 trace!(
437 "Resolved operation handler for network message {}::<{}>",
438 message.operation,
439 object_type
440 );
441
442 // Deserialize the operation
443 let meta = self
444 .metadata
445 .operations
446 .get(&target)
447 .ok_or_else(|| OperationError::Unhandled)?;
448
449 let operation =
450 (meta.deserialize)(&message.payload.0).as_internal_error_with_context(format!(
451 "deserializing operation {}::{}",
452 target.object_name, target.operation_name
453 ))?;
454
455 trace!(
456 "Deserialized operation for network message {}::<{}>",
457 message.operation,
458 object_type
459 );
460
461 trace!(
462 "Calling handler for network message {}::<{}>",
463 message.operation,
464 object_type
465 );
466
467 // Get the raw result of the operation, where the return values are boxed.
468 let raw_result = handler
469 .handle((object.clone(), operation.clone()), operation_state.clone())
470 .await;
471
472 trace!(
473 "Finished handling network message {}::<{}>",
474 message.operation,
475 object_type
476 );
477
478 // Deserialize the raw result for the network
479 match raw_result {
480 Ok(success) => Ok((meta.serialize_success)(success).as_internal_error()?),
481 Err(err) => Err(match err {
482 OperationError::Operation(failure) => {
483 OperationError::Operation((meta.serialize_error)(failure).as_internal_error()?)
484 }
485 OperationError::Internal(internal) => {
486 OperationError::Internal(internal.context(format!(
487 "operation {}::{} handler outcome",
488 target.object_name, target.operation_name
489 )))
490 }
491 OperationError::Unhandled => OperationError::Unhandled,
492 }),
493 }
494 }
495
496 pub async fn network_get_value(
497 &self,
498 object: AnyObject,
499 object_kind: String,
500 operation: GetValue,
501 operation_state: &StackOperationState,
502 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
503 trace!("Handling network get_value for {}", operation.value_name);
504
505 let value_meta = self
506 .metadata
507 .values
508 .get(&ObjectValuePair {
509 object_kind: &object_kind,
510 value_kind: &operation.value_name,
511 })
512 .ok_or_else(|| OperationError::Unhandled)?;
513
514 for (target, getter) in self.value_getters.iter() {
515 if target.object_kind != object_kind {
516 continue;
517 }
518
519 if target.value_kind != operation.value_name {
520 continue;
521 }
522
523 return match getter
524 .handle((object.clone(),), operation_state.clone())
525 .await
526 {
527 Ok(success) => {
528 // Serialize success, which is the value type itself
529 let serialized = (value_meta.serialize)(success).as_internal_error()?;
530
531 Ok(serialized)
532 }
533 Err(err) => Err(match err {
534 OperationError::Operation(failure) => {
535 // Failure is sourced from GetValue operation, but this is hardcoded for now
536 let failure: &GetValueError = failure.0.downcast_ref().unwrap();
537
538 OperationError::Operation(serde_json::to_vec(&failure).as_internal_error()?)
539 }
540 OperationError::Internal(internal) => OperationError::Internal(internal),
541 OperationError::Unhandled => OperationError::Unhandled,
542 }),
543 };
544 }
545
546 Err(OperationError::Unhandled)
547 }
548
549 pub async fn get_setting(
550 &self,
551 object: AnyObject,
552 object_kind: String,
553 operation: GetSetting,
554 _operation_state: &StackOperationState,
555 ) -> Result<AnySetting, OperationError<Box<dyn Any + Send + Sync>>> {
556 trace!(
557 "Handling network {}::get_setting for {}",
558 object_kind,
559 operation.setting_name
560 );
561
562 for provider in self.metadata_providers.iter() {
563 if provider.provides_for(object.0.as_ref()) {
564 let setting_meta = self
565 .metadata
566 .settings
567 .get(&ObjectSettingPair {
568 object_kind: &object_kind,
569 setting_name: &operation.setting_name,
570 })
571 .ok_or_else(|| OperationError::Unhandled)?;
572
573 let object_meta = self
574 .metadata
575 .objects
576 .get(&object_kind)
577 .ok_or_else(|| OperationError::Unhandled)?;
578
579 let result = provider
580 .read(object.clone(), object_meta, setting_meta)
581 .await
582 .as_internal_error_with_context(format!(
583 "reading setting {}",
584 operation.setting_name
585 ))?;
586
587 return (setting_meta.deserialize)(result).as_internal_error_with_context(format!(
588 "deserializing setting {}",
589 operation.setting_name
590 ));
591 }
592 }
593
594 trace!("setting {} doesn't exist", operation.setting_name);
595
596 Err(OperationError::Unhandled)
597 }
598
599 pub async fn network_set_setting(
600 &self,
601 object: AnyObject,
602 object_kind: String,
603 operation: SetSetting,
604 operation_state: &StackOperationState,
605 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
606 trace!(
607 "Handling network {}::set_setting for {}",
608 object_kind,
609 operation.setting_name
610 );
611
612 let target = ObjectSettingPair {
613 object_kind: &object_kind,
614 setting_name: &operation.setting_name,
615 };
616
617 let handler = self.setting_change.get(&target).unwrap();
618
619 let setting_meta = self
620 .metadata
621 .settings
622 .get(&ObjectSettingPair {
623 object_kind: &object_kind,
624 setting_name: &operation.setting_name,
625 })
626 .ok_or_else(|| OperationError::Unhandled)?;
627
628 let setting =
629 (setting_meta.deserialize)(operation.value).as_internal_error_with_context(format!(
630 "deserializing setting {} for object {}",
631 operation.setting_name, object_kind
632 ))?;
633
634 let raw_result = handler
635 .handle((object, setting.clone()), operation_state.clone())
636 .await;
637
638 match raw_result {
639 Ok(_) => {
640 // Serialize success, which is the value type itself
641 let serialized = serde_json::to_vec(&()).as_internal_error()?;
642
643 Ok(serialized)
644 }
645 Err(err) => Err(match err {
646 OperationError::Operation(operation) => OperationError::Internal(operation),
647 OperationError::Internal(internal) => OperationError::Internal(internal),
648 OperationError::Unhandled => OperationError::Unhandled,
649 }),
650 }
651 }
652 }
653
654 #[async_trait::async_trait(?Send)]
655 impl ObjectBackend<StackOperationState> for Arc<GiteratedStack> {
656 async fn object_operation<O, D>(
657 &self,
658 in_object: O,
659 operation_name: &str,
660 payload: D,
661 operation_state: &StackOperationState,
662 ) -> Result<D::Success, OperationError<D::Failure>>
663 where
664 O: GiteratedObject + Debug + 'static,
665 D: GiteratedOperation<O> + Debug + 'static,
666 D::Success: Clone,
667 D::Failure: Clone,
668 {
669 // Erase object and operation types.
670 let object = AnyObject(Arc::new(in_object.clone()) as Arc<dyn Any + Send + Sync>);
671 let operation = AnyOperation(Arc::new(payload) as Arc<dyn Any + Send + Sync>);
672
673 // We need to hijack get_value, set_setting, and get_setting.
674 if operation_name == "get_value" {
675 let mut value_meta = None;
676 for (_, meta) in self.metadata.values.iter() {
677 if (meta.is_get_value_typed)(operation.clone()) {
678 value_meta = Some(meta);
679 break;
680 }
681 }
682
683 let value_meta = value_meta.ok_or_else(|| OperationError::Unhandled)?;
684
685 let value_name = value_meta.name.clone();
686
687 trace!(
688 "Handling get_value for {}::{}",
689 O::object_name(),
690 value_name
691 );
692
693 for (target, getter) in self.value_getters.iter() {
694 if target.object_kind != O::object_name() {
695 continue;
696 }
697
698 if target.value_kind != value_name {
699 continue;
700 }
701
702 return match getter
703 .handle((object.clone(),), operation_state.clone())
704 .await
705 {
706 Ok(success) => Ok(success.0.downcast_ref::<D::Success>().unwrap().clone()),
707 Err(err) => Err(match err {
708 OperationError::Operation(failure) => OperationError::Operation(
709 failure.0.downcast_ref::<D::Failure>().unwrap().clone(),
710 ),
711 OperationError::Internal(internal) => {
712 OperationError::Internal(internal.context(format!(
713 "{}::get_value::<{}> handler outcome",
714 O::object_name(),
715 value_name
716 )))
717 }
718 OperationError::Unhandled => OperationError::Unhandled,
719 }),
720 };
721 }
722
723 return Err(OperationError::Unhandled);
724 } else if operation.0.is::<GetSetting>() {
725 let get_setting: &GetSetting = operation.0.downcast_ref().unwrap();
726 let setting_name = get_setting.setting_name.clone();
727
728 let raw_result = self
729 .get_setting(
730 object,
731 O::object_name().to_string(),
732 get_setting.clone(),
733 operation_state,
734 )
735 .await;
736
737 return match raw_result {
738 Ok(success) => {
739 // Success is the setting type, serialize it
740 // let serialized = (setting_meta.serialize)(success).unwrap();
741
742 // Ok(serde_json::to_vec(&serialized).unwrap())
743 Ok(success.0.downcast_ref::<D::Success>().unwrap().clone())
744 }
745 Err(err) => Err(match err {
746 OperationError::Operation(failure) => {
747 // We know this is the right type
748 OperationError::Operation(*failure.downcast().unwrap())
749 }
750 OperationError::Internal(internal) => {
751 OperationError::Internal(internal.context(format!(
752 "{}::get_setting::<{}> handler outcome",
753 O::object_name(),
754 setting_name
755 )))
756 }
757 OperationError::Unhandled => OperationError::Unhandled,
758 }),
759 };
760 } else if operation.0.is::<SetSetting>() {
761 todo!()
762 } else if operation.0.is::<ObjectRequest>() {
763 todo!()
764 }
765
766 // Resolve the operation from the known operations table.
767 let operation_type = {
768 let mut operation_type = None;
769
770 for (target, operation_meta) in self.metadata.operations.iter() {
771 // Skip elements that we know will not match
772 if target.object_name != O::object_name() {
773 continue;
774 }
775
776 if target.operation_name != operation_name {
777 continue;
778 }
779
780 if (operation_meta.any_is_same)(&operation) {
781 operation_type = Some(target.clone());
782 break;
783 }
784 }
785
786 operation_type
787 }
788 .ok_or_else(|| OperationError::Unhandled)?;
789
790 // Resolve the handler from our handler tree
791 let handler_tree = self
792 .operation_handlers
793 .get(&operation_type)
794 .ok_or_else(|| OperationError::Unhandled)?;
795
796 let raw_result = handler_tree
797 .handle((object, operation), operation_state.clone())
798 .await;
799
800 // Convert the dynamic result back into its concrete type
801 match raw_result {
802 Ok(result) => Ok(result.0.downcast_ref::<D::Success>().unwrap().clone()),
803 Err(err) => Err(match err {
804 OperationError::Internal(internal) => {
805 OperationError::Internal(internal.context(format!(
806 "operation {}::{} handler outcome",
807 operation_type.object_name, operation_type.operation_name
808 )))
809 }
810 OperationError::Operation(boxed_error) => OperationError::Operation(
811 boxed_error.0.downcast_ref::<D::Failure>().unwrap().clone(),
812 ),
813 OperationError::Unhandled => OperationError::Unhandled,
814 }),
815 }
816 }
817
818 async fn get_object<O>(
819 &self,
820 object_str: &str,
821 _operation_state: &StackOperationState,
822 ) -> Result<Object<StackOperationState, O, Self>, OperationError<ObjectRequestError>>
823 where
824 O: GiteratedObject + Debug + 'static,
825 {
826 // TODO: Authorization?
827 for (_object_name, object_meta) in self.metadata.objects.iter() {
828 if let Ok(object) = (object_meta.from_str)(object_str) {
829 return Ok(unsafe {
830 Object::new_unchecked(
831 object.0.downcast_ref::<O>().unwrap().clone(),
832 self.clone(),
833 )
834 });
835 }
836 }
837
838 Err(OperationError::Unhandled)
839 }
840 }
841
842 /// Defines a type that is a valid Giterated runtime state.
843 ///
844 /// This allows for extraction of state in handlers, based on a
845 /// [`FromOperationState<S>`] impl on (what is in this case) [`Self`].
846 pub trait GiteratedStackState: Send + Sync + Clone {}
847
848 impl<T: Send + Sync + Clone> GiteratedStackState for T {}
849
850 #[async_trait::async_trait(?Send)]
851 impl<R, S, T> HandlerResolvable<R, S> for Option<T>
852 where
853 T: HandlerResolvable<R, S>,
854 {
855 type Error = MissingValue;
856
857 async fn from_handler_state(
858 required_parameters: &R,
859 operation_state: &S,
860 ) -> Result<Option<T>, MissingValue> {
861 Ok(T::from_handler_state(required_parameters, operation_state)
862 .await
863 .ok())
864 }
865 }

giterated-stack/src/substack.rs

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

giterated-stack/src/update.rs

View file
@@ -116,20 +116,19 @@ impl HandleSettingUpdatedFunction {
116 116 setting_name: setting_name.to_string(),
117 117 },
118 118
119 function: Box::new(move |object, setting_name, value, state| {
119 function: Box::new(move |object, _setting_name, _value, _state| {
120 120 async move {
121 let mut handler = handler;
121 let _handler = handler;
122 122
123 let object = match O::from_str(&object) {
123 let _object = match O::from_str(&object) {
124 124 Ok(object) => object,
125 125 Err(_) => return Err(()),
126 126 };
127 127
128 let setting: S = serde_json::from_value(value.0).unwrap();
129
130 let _ = handler
131 .handle_setting_update(object, setting_name, setting, &state)
132 .await;
128 // let setting: S = serde_json::from_value(
129 // let _ = handler
130 // .handle_setting_update(object, setting_name, setting, &state)
131 // .await;value.0).unwrap();
133 132
134 133 Ok(())
135 134 }
@@ -168,20 +167,20 @@ impl HandleValueUpdatedFunction {
168 167 value_name: value_name.to_string(),
169 168 },
170 169
171 function: Box::new(move |object, setting_name, value, state| {
170 function: Box::new(move |object, _setting_name, _value, _state| {
172 171 async move {
173 let mut handler = handler;
172 let _handler = handler;
174 173
175 let object = match O::from_str(&object) {
174 let _object = match O::from_str(&object) {
176 175 Ok(object) => object,
177 176 Err(_) => return Err(()),
178 177 };
179 178
180 let setting: V = serde_json::from_value(value.0).unwrap();
179 // let setting: V = serde_json::from_value(value.0).unwrap();
181 180
182 let _ = handler
183 .handle_value_update(object, setting_name, setting, &state)
184 .await;
181 // let _ = handler
182 // .handle_value_update(object, setting_name, setting, &state)
183 // .await;
185 184
186 185 Ok(())
187 186 }