From 570c194e82983e9eb7678ae82fe30834e49fe66e Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 16 Apr 2023 22:57:12 -0400 Subject: [PATCH] Macros for frontend nRPC service generation --- Cargo.lock | 896 ++++++++++++++++----- Cargo.toml | 30 +- usdpl-back/Cargo.toml | 18 +- usdpl-back/build.rs | 3 + usdpl-back/src/api_common/dirs.rs | 6 - usdpl-back/src/api_crankshaft/mod.rs | 1 - usdpl-back/src/rpc/mod.rs | 0 usdpl-build/Cargo.toml | 18 + usdpl-build/protos/debug.proto | 25 + usdpl-build/protos/translations.proto | 19 + usdpl-build/src/back/mod.rs | 7 + usdpl-build/src/front/mod.rs | 22 + usdpl-build/src/front/preprocessor.rs | 27 + usdpl-build/src/front/service_generator.rs | 592 ++++++++++++++ usdpl-build/src/front/shared_state.rs | 26 + usdpl-build/src/lib.rs | 5 + usdpl-build/src/proto_files.rs | 44 + usdpl-core/Cargo.toml | 7 +- usdpl-core/src/api_common/target.rs | 7 - usdpl-core/src/api_crankshaft/mod.rs | 1 - usdpl-core/src/socket.rs | 8 - usdpl-front/Cargo.toml | 19 +- usdpl-front/build.rs | 3 + usdpl-front/src/client_handler.rs | 81 ++ usdpl-front/src/lib.rs | 9 +- 25 files changed, 1612 insertions(+), 262 deletions(-) create mode 100644 usdpl-back/build.rs delete mode 100644 usdpl-back/src/api_crankshaft/mod.rs create mode 100644 usdpl-back/src/rpc/mod.rs create mode 100644 usdpl-build/Cargo.toml create mode 100644 usdpl-build/protos/debug.proto create mode 100644 usdpl-build/protos/translations.proto create mode 100644 usdpl-build/src/back/mod.rs create mode 100644 usdpl-build/src/front/mod.rs create mode 100644 usdpl-build/src/front/preprocessor.rs create mode 100644 usdpl-build/src/front/service_generator.rs create mode 100644 usdpl-build/src/front/shared_state.rs create mode 100644 usdpl-build/src/lib.rs create mode 100644 usdpl-build/src/proto_files.rs delete mode 100644 usdpl-core/src/api_crankshaft/mod.rs create mode 100644 usdpl-front/build.rs create mode 100644 usdpl-front/src/client_handler.rs diff --git a/Cargo.lock b/Cargo.lock index 340a0bd..8af7fe1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,25 +39,42 @@ dependencies = [ ] [[package]] -name = "async-recursion" -version = "1.0.2" +name = "anyhow" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-recursion" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "async-trait" -version = "0.1.64" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -72,6 +89,18 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bitflags" version = "1.3.2" @@ -80,23 +109,13 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] -[[package]] -name = "buf_redux" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" -dependencies = [ - "memchr", - "safemem", -] - [[package]] name = "bumpalo" version = "3.12.0" @@ -115,6 +134,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -130,6 +155,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -142,13 +176,22 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -178,6 +221,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + [[package]] name = "encoding" version = "0.2.33" @@ -242,6 +291,33 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "fastrand" version = "1.9.0" @@ -251,6 +327,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "fnv" version = "1.0.7" @@ -267,10 +349,25 @@ dependencies = [ ] [[package]] -name = "futures-channel" -version = "0.3.26" +name = "futures" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -278,31 +375,63 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -310,9 +439,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -320,9 +449,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -340,10 +469,43 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.15" +name = "gloo-net" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-utils" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "h2" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" dependencies = [ "bytes", "fnv", @@ -370,7 +532,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64", + "base64 0.13.1", "bitflags", "bytes", "headers-core", @@ -389,6 +551,12 @@ dependencies = [ "http", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -398,6 +566,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -446,9 +620,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.24" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -480,9 +654,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -498,10 +672,30 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.5" +name = "io-lifetimes" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" @@ -513,10 +707,22 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.139" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "log" @@ -527,6 +733,38 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax", + "syn 2.0.15", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + [[package]] name = "memchr" version = "2.5.0" @@ -534,10 +772,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "mime" -version = "0.3.16" +name = "miette" +version = "5.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "7abdc09c381c9336b9f2e9bd6067a9a5290d20e2d2e2296f275456121c33ae89" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8842972f23939443013dfd3720f46772b743e86f1a81d120d4b6fb090f87de1c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -562,21 +823,50 @@ dependencies = [ ] [[package]] -name = "multipart" -version = "0.18.0" +name = "multimap" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "multiparty" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1ec6589a6d4a1e0b33b4c0a3f6ee96dfba88ebdb3da51403fd7cf0a24a4b04" dependencies = [ - "buf_redux", + "bytes", + "futures-core", "httparse", - "log", - "mime", - "mime_guess", - "quick-error", - "rand", - "safemem", - "tempfile", - "twoway", + "memchr", + "pin-project-lite", + "try-lock", +] + +[[package]] +name = "nrpc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8770a9a12e53035a536e41b7899d72bc423b2b8c17402c8f0dbe44d6bb255ac6" +dependencies = [ + "async-trait", + "bytes", + "prost", +] + +[[package]] +name = "nrpc-build" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5914c2bfd187a4bdfa7a69330e1ef4d8dea4060d8a08bf146f622aa7f176680" +dependencies = [ + "nrpc", + "prettyplease 0.2.4", + "proc-macro2", + "prost-build", + "prost-types", + "protox", + "quote", + "syn 2.0.15", ] [[package]] @@ -585,7 +875,7 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -613,6 +903,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "pin-project" version = "1.0.12" @@ -630,7 +930,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -664,25 +964,133 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "proc-macro2" -version = "1.0.51" +name = "prettyplease" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "prettyplease" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058" +dependencies = [ + "proc-macro2", + "syn 2.0.15", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "prost" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease 0.1.25", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-reflect" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4df26814fb2cd59b1764305047aac8e9c467efe84a9e51bfd0c8811f08fe88a" +dependencies = [ + "logos", + "miette", + "once_cell", + "prost", + "prost-types", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "protox" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb2d1d74977bfa8fc4ddac1951ea639197c2896a830b6c5640085e498726da2" +dependencies = [ + "bytes", + "miette", + "prost", + "prost-reflect", + "prost-types", + "protox-parse", + "thiserror", +] + +[[package]] +name = "protox-parse" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df78235a8c28dc4c5d8acb498d3000851b61b80a68774ff7b43323371b082ea4" +dependencies = [ + "logos", + "miette", + "prost-types", + "thiserror", +] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -719,42 +1127,56 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "regex" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ - "winapi", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "rustix" +version = "0.37.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustls-pemfile" -version = "0.2.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" - -[[package]] -name = "safemem" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "scoped-tls" @@ -764,15 +1186,15 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -791,17 +1213,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha1" version = "0.10.5" @@ -815,18 +1226,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -840,9 +1251,20 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -851,36 +1273,35 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -900,26 +1321,25 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.25.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "pin-project-lite", "socket2", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" dependencies = [ "futures-core", "pin-project-lite", @@ -928,9 +1348,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.17.2" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" dependencies = [ "futures-util", "log", @@ -987,32 +1407,23 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.17.3" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "bytes", "http", "httparse", "log", "rand", - "sha-1", + "sha1", "thiserror", "url", "utf-8", ] -[[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr", -] - [[package]] name = "typenum" version = "1.16.0" @@ -1030,15 +1441,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -1049,6 +1460,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "universal-hash" version = "0.4.1" @@ -1070,13 +1487,9 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "usdpl" -version = "0.10.0" - [[package]] name = "usdpl-back" -version = "0.10.1" +version = "0.11.0" dependencies = [ "async-recursion", "async-trait", @@ -1084,29 +1497,50 @@ dependencies = [ "gettext-ng", "hex", "log", + "nrpc", "obfstr", "tokio", + "usdpl-build", "usdpl-core", "warp", ] +[[package]] +name = "usdpl-build" +version = "0.11.0" +dependencies = [ + "nrpc-build", + "prettyplease 0.2.4", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.15", +] + [[package]] name = "usdpl-core" -version = "0.10.0" +version = "0.11.0" dependencies = [ "aes-gcm-siv", - "base64", + "base64 0.13.1", "hex-literal", ] [[package]] name = "usdpl-front" -version = "0.10.1" +version = "0.11.0" dependencies = [ + "async-channel", "console_error_panic_hook", + "futures", + "gloo-net", "hex", "js-sys", + "nrpc", "obfstr", + "prost", + "usdpl-build", "usdpl-core", "wasm-bindgen", "wasm-bindgen-futures", @@ -1138,9 +1572,9 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7b8be92646fc3d18b06147664ebc5f48d222686cb11a8755e561a735aacc6d" +checksum = "27e1a710288f0f91a98dd8a74f05b76a10768db245ce183edf64dc1afdc3016c" dependencies = [ "bytes", "futures-channel", @@ -1151,7 +1585,7 @@ dependencies = [ "log", "mime", "mime_guess", - "multipart", + "multiparty", "percent-encoding", "pin-project", "rustls-pemfile", @@ -1194,7 +1628,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] @@ -1228,7 +1662,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1273,6 +1707,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1295,86 +1740,137 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - [[package]] name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "zeroize" diff --git a/Cargo.toml b/Cargo.toml index 7d15700..4c8660f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,14 @@ -[package] -name = "usdpl" -version = "0.10.0" -authors = ["NGnius (Graham) "] -edition = "2021" -license = "GPL-3.0-only" -repository = "https://github.com/NGnius/usdpl-rs" -readme = "README.md" +[workspace] +members = [ + "usdpl-core", + "usdpl-front", + "usdpl-back", + "usdpl-build", +] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +exclude = [ + "templates/decky/backend" +] [profile.release] # Tell `rustc` to optimize for small code size. @@ -16,14 +17,3 @@ debug = false strip = true lto = true codegen-units = 4 - -[workspace] -members = [ - "usdpl-core", - "usdpl-front", - "usdpl-back", -] - -exclude = [ - "templates/decky/backend" -] diff --git a/usdpl-back/Cargo.toml b/usdpl-back/Cargo.toml index 69807b4..4941d35 100644 --- a/usdpl-back/Cargo.toml +++ b/usdpl-back/Cargo.toml @@ -1,25 +1,26 @@ [package] name = "usdpl-back" -version = "0.10.1" +version = "0.11.0" edition = "2021" license = "GPL-3.0-only" repository = "https://github.com/NGnius/usdpl-rs" -readme = "README.md" +readme = "../README.md" description = "Universal Steam Deck Plugin Library back-end" [features] -default = ["blocking", "translate"] +default = ["blocking"] decky = ["usdpl-core/decky"] -crankshaft = ["usdpl-core/crankshaft"] blocking = ["tokio", "tokio/rt", "tokio/rt-multi-thread"] # synchronous API for async functionality, using tokio encrypt = ["usdpl-core/encrypt", "obfstr", "hex"] -translate = ["usdpl-core/translate", "gettext-ng"] [dependencies] -usdpl-core = { version = "0.10", path = "../usdpl-core"} +usdpl-core = { version = "0.11", path = "../usdpl-core"} log = "0.4" +# gRPC/protobuf +nrpc = "0.2" + # HTTP web framework warp = { version = "0.3" } bytes = { version = "1.1" } @@ -34,4 +35,7 @@ obfstr = { version = "0.3", optional = true } hex = { version = "0.4", optional = true } # translations -gettext-ng = { version = "0.4.1", optional = true } +gettext-ng = { version = "0.4.1" } + +[build-dependencies] +usdpl-build = { version = "0.11", path = "../usdpl-build" } diff --git a/usdpl-back/build.rs b/usdpl-back/build.rs new file mode 100644 index 0000000..36803b5 --- /dev/null +++ b/usdpl-back/build.rs @@ -0,0 +1,3 @@ +fn main() { + usdpl_build::back::build() +} diff --git a/usdpl-back/src/api_common/dirs.rs b/usdpl-back/src/api_common/dirs.rs index b07f347..033aee6 100644 --- a/usdpl-back/src/api_common/dirs.rs +++ b/usdpl-back/src/api_common/dirs.rs @@ -6,8 +6,6 @@ use std::path::PathBuf; pub fn home() -> Option { #[cfg(not(any(feature = "decky", feature = "crankshaft")))] let result = crate::api_any::dirs::home(); - #[cfg(all(feature = "crankshaft", not(any(feature = "decky"))))] - let result = None; // TODO #[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))] let result = crate::api_decky::home().ok() .map(|x| PathBuf::from(x) @@ -23,8 +21,6 @@ pub fn home() -> Option { pub fn plugin() -> Option { #[cfg(not(any(feature = "decky", feature = "crankshaft")))] let result = None; // TODO - #[cfg(all(feature = "crankshaft", not(any(feature = "decky"))))] - let result = None; // TODO #[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))] let result = crate::api_decky::plugin_dir().ok().map(|x| x.into()); @@ -35,8 +31,6 @@ pub fn plugin() -> Option { pub fn log() -> Option { #[cfg(not(any(feature = "decky", feature = "crankshaft")))] let result = crate::api_any::dirs::log(); - #[cfg(all(feature = "crankshaft", not(any(feature = "decky"))))] - let result = None; // TODO #[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))] let result = crate::api_decky::log_dir().ok().map(|x| x.into()); diff --git a/usdpl-back/src/api_crankshaft/mod.rs b/usdpl-back/src/api_crankshaft/mod.rs deleted file mode 100644 index c040648..0000000 --- a/usdpl-back/src/api_crankshaft/mod.rs +++ /dev/null @@ -1 +0,0 @@ -compile_error!("Crankshaft unsupported (project no longer maintained)"); diff --git a/usdpl-back/src/rpc/mod.rs b/usdpl-back/src/rpc/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/usdpl-build/Cargo.toml b/usdpl-build/Cargo.toml new file mode 100644 index 0000000..f2f4ab7 --- /dev/null +++ b/usdpl-build/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "usdpl-build" +version = "0.11.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +nrpc-build = "0.5" +prost-build = "0.11" +prost-types = "0.11" + +# code gen +prettyplease = "0.2" +quote = "1.0" +syn = "2.0" +proc-macro2 = "1.0" + diff --git a/usdpl-build/protos/debug.proto b/usdpl-build/protos/debug.proto new file mode 100644 index 0000000..c5b7168 --- /dev/null +++ b/usdpl-build/protos/debug.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package usdpl; + +// The translation service +service DevTools { + // Retrieves all translations for the provided 4-letter code + rpc Log (LogMessage) returns (Empty); +} + +enum LogLevel { + Trace = 0; + Debug = 1; + Info = 2; + Warn = 3; + Error = 4; +} + +// The request message containing the log message +message LogMessage { + LogLevel level = 1; + string msg = 2; +} + +message Empty {} diff --git a/usdpl-build/protos/translations.proto b/usdpl-build/protos/translations.proto new file mode 100644 index 0000000..3fc4e59 --- /dev/null +++ b/usdpl-build/protos/translations.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package usdpl; + +// The translation service +service Translations { + // Retrieves all translations for the provided 4-letter code + rpc GetLanguage (LanguageRequest) returns (TranslationsReply) {} +} + +// The request message containing the language code +message LanguageRequest { + string lang = 1; +} + +// The response message containing all translations for the language +message TranslationsReply { + map translations = 1; +} diff --git a/usdpl-build/src/back/mod.rs b/usdpl-build/src/back/mod.rs new file mode 100644 index 0000000..65d0120 --- /dev/null +++ b/usdpl-build/src/back/mod.rs @@ -0,0 +1,7 @@ +pub fn build() { + crate::dump_protos_out().unwrap(); + nrpc_build::compile_servers( + crate::all_proto_filenames().map(|n| crate::proto_out_path().clone().join(n)), + [crate::proto_out_path()] + ) +} diff --git a/usdpl-build/src/front/mod.rs b/usdpl-build/src/front/mod.rs new file mode 100644 index 0000000..698aa9d --- /dev/null +++ b/usdpl-build/src/front/mod.rs @@ -0,0 +1,22 @@ +mod preprocessor; +pub use preprocessor::WasmProtoPreprocessor; + +mod service_generator; +pub use service_generator::WasmServiceGenerator; + +mod shared_state; +pub(crate) use shared_state::SharedState; + +pub fn build() { + let shared_state = SharedState::new(); + crate::dump_protos_out().unwrap(); + nrpc_build::Transpiler::new( + crate::all_proto_filenames().map(|n| crate::proto_out_path().clone().join(n)), + [crate::proto_out_path()] + ).unwrap() + .generate_client() + .with_preprocessor(nrpc_build::AbstractImpl::outer(WasmProtoPreprocessor::with_state(&shared_state))) + .with_service_generator(nrpc_build::AbstractImpl::outer(WasmServiceGenerator::with_state(&shared_state))) + .transpile() + .unwrap() +} diff --git a/usdpl-build/src/front/preprocessor.rs b/usdpl-build/src/front/preprocessor.rs new file mode 100644 index 0000000..dd3b4a2 --- /dev/null +++ b/usdpl-build/src/front/preprocessor.rs @@ -0,0 +1,27 @@ +use nrpc_build::IPreprocessor; +//use prost_build::{Service, ServiceGenerator}; +use prost_types::FileDescriptorSet; + +use super::SharedState; + +pub struct WasmProtoPreprocessor { + shared: SharedState, +} + +impl WasmProtoPreprocessor { + pub fn with_state(state: &SharedState) -> Self { + Self { + shared: state.clone(), + } + } +} + +impl IPreprocessor for WasmProtoPreprocessor { + fn process(&mut self, fds: &mut FileDescriptorSet) -> proc_macro2::TokenStream { + self.shared.lock() + .expect("Cannot lock shared state") + .fds = Some(fds.clone()); + quote::quote!{} + } +} + diff --git a/usdpl-build/src/front/service_generator.rs b/usdpl-build/src/front/service_generator.rs new file mode 100644 index 0000000..173a757 --- /dev/null +++ b/usdpl-build/src/front/service_generator.rs @@ -0,0 +1,592 @@ +use std::collections::HashSet; + +use prost_build::Service; +use prost_types::{FileDescriptorSet, DescriptorProto, EnumDescriptorProto, FieldDescriptorProto}; +use nrpc_build::IServiceGenerator; + +use super::SharedState; + +pub struct WasmServiceGenerator { + shared: SharedState, +} + +impl WasmServiceGenerator { + pub fn with_state(state: &SharedState) -> Self { + Self { + shared: state.clone(), + } + } +} + +fn generate_service_methods(service: &Service, fds: &FileDescriptorSet) -> proc_macro2::TokenStream { + let mut gen_methods = Vec::with_capacity(service.methods.len()); + for method in &service.methods { + let method_name = quote::format_ident!("{}", method.name); + let method_input = quote::format_ident!("{}{}", &service.name, method.input_type); + let method_output = quote::format_ident!("{}{}", &service.name, method.output_type); + + let input_type = find_message_type(&method.input_type, &service.package, fds).expect("Protobuf message is used but not found"); + + let mut input_params = Vec::with_capacity(input_type.field.len()); + let mut params_to_fields = Vec::with_capacity(input_type.field.len()); + for field in &input_type.field { + //let param_name = quote::format_ident!("val{}", i.to_string()); + let type_name = translate_type(field, &service.name); + let field_name = quote::format_ident!("{}", field.name.as_ref().expect("Protobuf message field needs a name")); + input_params.push(quote::quote!{ + #field_name: #type_name, + }); + params_to_fields.push(quote::quote!{ + #field_name,//: #field_name, + }); + } + let params_to_fields_transformer = if input_type.field.len() == 1 { + let field_name = quote::format_ident!("{}", input_type.field[0].name.as_ref().expect("Protobuf message field needs a name")); + quote::quote!{ + let val = #field_name; + } + } else if input_type.field.is_empty() { + quote::quote!{ + let val = #method_input {}; + } + } else { + quote::quote!{ + let val = #method_input { + #(#params_to_fields)* + }; + } + }; + + let special_fn_into_input = quote::format_ident!("{}_convert_into", method.input_type.split('.').last().unwrap().to_lowercase()); + + let special_fn_from_output = quote::format_ident!("{}_convert_from", method.output_type.split('.').last().unwrap().to_lowercase()); + + gen_methods.push( + quote::quote!{ + #[wasm_bindgen] + pub async fn #method_name(&mut self, #(#input_params)*) -> Option<#method_output> { + + #params_to_fields_transformer + + match self.service.#method_name(#special_fn_into_input(val)).await { + Ok(x) => Some(#special_fn_from_output(x)), + Err(_e) => { + // TODO log error + None + } + } + } + } + ); + } + quote::quote!{ + #(#gen_methods)* + } +} + +fn find_message_type<'a>(want_type: &str, want_package: &str, fds: &'a FileDescriptorSet) -> Option<&'a DescriptorProto> { + for file in &fds.file { + for message_type in &file.message_type { + if let Some(name) = &message_type.name { + if let Some(pkg) = &file.package { + if name == want_type && pkg == want_package { + return Some(message_type); + } + } + } + } + } + None +} + +fn find_enum_type<'a>(want_type: &str, want_package: &str, fds: &'a FileDescriptorSet) -> Option<&'a EnumDescriptorProto> { + for file in &fds.file { + for enum_type in &file.enum_type { + if let Some(name) = &enum_type.name { + if let Some(pkg) = &file.package { + if name == want_type && pkg == want_package { + return Some(enum_type); + } + } + } + } + } + None +} + +fn find_field<'a>(want_field: &str, descriptor: &'a DescriptorProto) -> Option<&'a FieldDescriptorProto> { + for field in &descriptor.field { + if let Some(name) = &field.name { + if name == want_field { + return Some(field); + } + } + } + None +} + +fn translate_type(field: &FieldDescriptorProto, service: &str) -> proc_macro2::TokenStream { + if let Some(type_name) = &field.type_name { + translate_type_name(type_name, service) + } else { + let number = field.r#type.unwrap(); + translate_type_known(number) + } +} + +fn generate_wasm_struct_interop(descriptor: &DescriptorProto, handled_enums: &mut HashSet, handled_types: &mut HashSet, is_response_msg: bool, service: &str) -> proc_macro2::TokenStream { + let msg_name = quote::format_ident!("{}{}", service, descriptor.name.as_ref().expect("Protobuf message needs a name")); + let super_msg_name = quote::format_ident!("{}", descriptor.name.as_ref().expect("Protobuf message needs a name")); + let mut gen_fields = Vec::with_capacity(descriptor.field.len()); + let mut gen_into_fields = Vec::with_capacity(descriptor.field.len()); + let mut gen_from_fields = Vec::with_capacity(descriptor.field.len()); + + let mut gen_nested_types = Vec::with_capacity(descriptor.nested_type.len()); + + let mut gen_enums = Vec::with_capacity(descriptor.enum_type.len()); + + if let Some(options) = &descriptor.options { + if let Some(map_entry) = options.map_entry { + // TODO deal with options when necessary + if map_entry { + let name = descriptor.name.clone().expect("Protobuf message needs a name"); + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + let key_field = find_field("key", descriptor).expect("Protobuf map entry has no key field"); + let key_type = translate_type(&key_field, service); + let value_field = find_field("value", descriptor).expect("Protobuf map entry has no value field"); + let value_type = translate_type(&value_field, service); + return quote::quote!{ + pub type #msg_name = ::js_sys::Map; + + #[inline] + #[allow(dead_code)] + fn #special_fn_from(other: ::std::collections::HashMap<#key_type, #value_type>) -> #msg_name { + let map = #msg_name::new(); + for (key, val) in other.iter() { + map.set(&key.into(), &val.into()); + } + map + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_into(this: #msg_name) -> ::std::collections::HashMap<#key_type, #value_type> { + let mut output = ::std::collections::HashMap::<#key_type, #value_type>::new(); + this.for_each(&mut |key: ::wasm_bindgen::JsValue, val: ::wasm_bindgen::JsValue| { + if let Some(key) = key.as_string() { + if let Some(val) = val.as_string() { + output.insert(key, val); + } + } + }); + output + } + } + } + } else { + todo!("Deal with message options when necessary"); + } + } + + for n_type in &descriptor.nested_type { + let type_name = n_type.name.clone().expect("Protobuf nested message needs a name"); + if !handled_types.contains(&type_name) { + handled_types.insert(type_name); + gen_nested_types.push(generate_wasm_struct_interop(n_type, handled_enums, handled_types, is_response_msg, service)); + } + } + + for e_type in &descriptor.enum_type { + let type_name = e_type.name.clone().expect("Protobuf enum needs a name"); + if !handled_enums.contains(&type_name) { + handled_enums.insert(type_name); + gen_enums.push(generate_wasm_enum_interop(e_type, service)); + } + } + if descriptor.field.len() == 1 { + let field = &descriptor.field[0]; + let field_name = quote::format_ident!("{}", field.name.as_ref().expect("Protobuf message field needs a name")); + let type_name = translate_type(field, service); + gen_fields.push(quote::quote!{ + pub #field_name: #type_name, + }); + if let Some(name) = &field.type_name { + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + gen_into_fields.push( + quote::quote!{ + #field_name: #special_fn_into(this) + } + ); + + gen_from_fields.push( + quote::quote!{ + #special_fn_from(other.#field_name) + } + ); + } else { + gen_into_fields.push( + quote::quote!{ + #field_name: this + } + ); + + gen_from_fields.push( + quote::quote!{ + other.#field_name + } + ); + } + + let name = descriptor.name.clone().expect("Protobuf message needs a name"); + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + + quote::quote!{ + pub type #msg_name = #type_name; + + #[inline] + #[allow(dead_code)] + fn #special_fn_from(other: super::#super_msg_name) -> #msg_name { + #(#gen_from_fields)* + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_into(this: #msg_name) -> super::#super_msg_name { + super::#super_msg_name { + #(#gen_into_fields)* + } + } + + #(#gen_nested_types)* + + #(#gen_enums)* + } + } else { + for field in &descriptor.field { + let field_name = quote::format_ident!("{}", field.name.as_ref().expect("Protobuf message field needs a name")); + let type_name = translate_type(field, service); + gen_fields.push(quote::quote!{ + pub #field_name: #type_name, + }); + if let Some(name) = &field.type_name { + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + gen_into_fields.push( + quote::quote!{ + #field_name: #special_fn_into(self.#field_name), + } + ); + + gen_from_fields.push( + quote::quote!{ + #field_name: #special_fn_from(other.#field_name), + } + ); + } else { + gen_into_fields.push( + quote::quote!{ + #field_name: self.#field_name, + } + ); + + gen_from_fields.push( + quote::quote!{ + #field_name: other.#field_name, + } + ); + } + } + + let name = descriptor.name.clone().expect("Protobuf message needs a name"); + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + + let wasm_attribute_maybe = if descriptor.field.len() == 1 || !is_response_msg { + quote::quote!{} + } else { + quote::quote!{ + #[wasm_bindgen] + } + }; + + quote::quote!{ + #wasm_attribute_maybe + pub struct #msg_name { + #(#gen_fields)* + } + + impl std::convert::Into for #msg_name { + #[inline] + fn into(self) -> super::#super_msg_name { + super::#super_msg_name { + #(#gen_into_fields)* + } + } + } + + impl std::convert::From for #msg_name { + #[inline] + #[allow(unused_variables)] + fn from(other: super::#super_msg_name) -> Self { + #msg_name { + #(#gen_from_fields)* + } + } + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_from(other: super::#super_msg_name) -> #msg_name { + #msg_name::from(other) + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_into(this: #msg_name) -> super::#super_msg_name { + this.into() + } + + #(#gen_nested_types)* + + #(#gen_enums)* + } + } + +} + +fn translate_type_name(name: &str, service: &str) -> proc_macro2::TokenStream { + match name { + "double" => quote::quote!{f64}, + "float" => quote::quote!{f32}, + "int32" => quote::quote!{i32}, + "int64" => quote::quote!{i64}, + "uint32" => quote::quote!{u32}, + "uint64" => quote::quote!{u64}, + "sint32" => quote::quote!{i32}, + "sint64" => quote::quote!{i64}, + "fixed32" => quote::quote!{u32}, + "fixed64" => quote::quote!{u64}, + "sfixed32" => quote::quote!{i32}, + "sfixed64" => quote::quote!{i64}, + "bool" => quote::quote!{bool}, + "string" => quote::quote!{String}, + "bytes" => quote::quote!{Vec}, + t => { + let ident = quote::format_ident!("{}{}", service, t.split('.').last().unwrap()); + quote::quote!{#ident} + }, + } +} + +fn translate_type_known(id: i32) -> proc_macro2::TokenStream { + match id { + //"double" => quote::quote!{f64}, + //"float" => quote::quote!{f32}, + //"int32" => quote::quote!{i32}, + //"int64" => quote::quote!{i64}, + //"uint32" => quote::quote!{u32}, + //"uint64" => quote::quote!{u64}, + //"sint32" => quote::quote!{i32}, + //"sint64" => quote::quote!{i64}, + //"fixed32" => quote::quote!{u32}, + //"fixed64" => quote::quote!{u64}, + //"sfixed32" => quote::quote!{i32}, + //"sfixed64" => quote::quote!{i64}, + //"bool" => quote::quote!{bool}, + 9 => quote::quote!{String}, + //"bytes" => quote::quote!{Vec}, + t => { + let ident = quote::format_ident!("UnknownType{}", t.to_string()); + quote::quote!{#ident} + }, + } +} + +fn generate_wasm_enum_interop(descriptor: &EnumDescriptorProto, service: &str) -> proc_macro2::TokenStream { + let enum_name = quote::format_ident!("{}{}", service, descriptor.name.as_ref().expect("Protobuf enum needs a name")); + let super_enum_name = quote::format_ident!("{}", descriptor.name.as_ref().expect("Protobuf enum needs a name")); + let mut gen_values = Vec::with_capacity(descriptor.value.len()); + let mut gen_into_values = Vec::with_capacity(descriptor.value.len()); + let mut gen_from_values = Vec::with_capacity(descriptor.value.len()); + if let Some(_options) = &descriptor.options { + // TODO deal with options when necessary + todo!("Deal with enum options when necessary"); + } + for value in &descriptor.value { + let val_name = quote::format_ident!("{}", value.name.as_ref().expect("Protobuf enum value needs a name")); + if let Some(_val_options) = &value.options { + // TODO deal with options when necessary + todo!("Deal with enum value options when necessary"); + } else { + if let Some(number) = &value.number { + gen_values.push( + quote::quote!{ + #val_name = #number, + } + ); + } else { + gen_values.push( + quote::quote!{ + #val_name, + } + ); + } + gen_into_values.push( + quote::quote!{ + Self::#val_name => super::#super_enum_name::#val_name, + } + ); + + gen_from_values.push( + quote::quote!{ + super::#super_enum_name::#val_name => Self::#val_name, + } + ); + } + } + let name = descriptor.name.clone().expect("Protobuf message needs a name"); + let special_fn_from = quote::format_ident!("{}_convert_from", name.split('.').last().unwrap().to_lowercase()); + let special_fn_into = quote::format_ident!("{}_convert_into", name.split('.').last().unwrap().to_lowercase()); + + quote::quote!{ + #[wasm_bindgen] + #[repr(i32)] + #[derive(Clone, Copy)] + pub enum #enum_name { + #(#gen_values)* + } + + impl std::convert::Into for #enum_name { + fn into(self) -> super::#super_enum_name { + match self { + #(#gen_into_values)* + } + } + } + + impl std::convert::From for #enum_name { + fn from(other: super::#super_enum_name) -> Self { + match other { + #(#gen_from_values)* + } + } + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_from(other: i32) -> #enum_name { + #enum_name::from(super::#super_enum_name::from_i32(other).unwrap()) + } + + #[inline] + #[allow(dead_code)] + fn #special_fn_into(this: #enum_name) -> i32 { + this as i32 + } + } +} + +fn generate_service_io_types(service: &Service, fds: &FileDescriptorSet) -> proc_macro2::TokenStream { + let mut gen_types = Vec::with_capacity(service.methods.len() * 2); + let mut gen_enums = Vec::new(); + let mut handled_enums = HashSet::new(); + let mut handled_types = HashSet::new(); + for method in &service.methods { + if let Some(input_message) = find_message_type(&method.input_type, &service.package, fds) { + let msg_name = input_message.name.clone().expect("Protobuf message name required"); + if !handled_types.contains(&msg_name) { + handled_types.insert(msg_name); + gen_types.push(generate_wasm_struct_interop(input_message, &mut handled_enums, &mut handled_types, false, &service.name)); + } + } else if let Some(input_enum) = find_enum_type(&method.input_type, &service.package, fds) { + let enum_name = input_enum.name.clone().expect("Protobuf enum name required"); + if !handled_enums.contains(&enum_name) { + handled_enums.insert(enum_name); + gen_types.push(generate_wasm_enum_interop(input_enum, &service.name)); + } + } else { + panic!("Cannot find proto type {}/{}", service.package, method.input_type); + } + + if let Some(output_message) = find_message_type(&method.output_type, &service.package, fds) { + let msg_name = output_message.name.clone().expect("Protobuf message name required"); + if !handled_types.contains(&msg_name) { + handled_types.insert(msg_name); + gen_types.push(generate_wasm_struct_interop(output_message, &mut handled_enums, &mut handled_types, true, &service.name)); + } + } else if let Some(output_enum) = find_enum_type(&method.output_type, &service.package, fds) { + let enum_name = output_enum.name.clone().expect("Protobuf enum name required"); + if !handled_enums.contains(&enum_name) { + handled_enums.insert(enum_name); + gen_types.push(generate_wasm_enum_interop(output_enum, &service.name)); + } + } else { + panic!("Cannot find proto type {}/{}", service.package, method.input_type); + } + } + + // always generate all enums, since they aren't encountered (ever, afaik) when generating message structs + for file in &fds.file { + for enum_type in &file.enum_type { + let enum_name = enum_type.name.clone().expect("Protobuf enum name required"); + if !handled_enums.contains(&enum_name) { + handled_enums.insert(enum_name); + gen_enums.push(generate_wasm_enum_interop(enum_type, &service.name)); + } + } + } + quote::quote! { + #(#gen_types)* + + #(#gen_enums)* + } +} + +impl IServiceGenerator for WasmServiceGenerator { + fn generate(&mut self, service: Service) -> proc_macro2::TokenStream { + let lock = self.shared.lock() + .expect("Cannot lock shared state"); + let fds = lock.fds + .as_ref() + .expect("FileDescriptorSet required for WASM service generator"); + let service_struct_name = quote::format_ident!("{}Client", service.name); + let service_js_name = quote::format_ident!("{}", service.name); + let service_methods = generate_service_methods(&service, fds); + let service_types = generate_service_io_types(&service, fds); + let mod_name = quote::format_ident!("js_{}", service.name.to_lowercase()); + quote::quote!{ + mod #mod_name { + use wasm_bindgen::prelude::*; + + use crate::client_handler::WebSocketHandler; + + #service_types + + /// WASM/JS-compatible wrapper of the Rust nRPC service + #[wasm_bindgen] + pub struct #service_js_name { + //#[wasm_bindgen(skip)] + service: super::#service_struct_name, + } + + #[wasm_bindgen] + impl #service_js_name { + #[wasm_bindgen(constructor)] + pub fn new(port: u16) -> Self { + let implementation = super::#service_struct_name::new( + WebSocketHandler::new(port) + ); + Self { + service: implementation, + } + } + + #service_methods + } + } + } + } +} diff --git a/usdpl-build/src/front/shared_state.rs b/usdpl-build/src/front/shared_state.rs new file mode 100644 index 0000000..2175d1d --- /dev/null +++ b/usdpl-build/src/front/shared_state.rs @@ -0,0 +1,26 @@ +use std::sync::{Arc, Mutex}; + +use prost_types::FileDescriptorSet; + +#[derive(Clone)] +pub struct SharedState(Arc>); + +impl SharedState { + pub fn new() -> Self { + Self(Arc::new(Mutex::new(SharedProtoData { + fds: None, + }))) + } +} + +impl std::ops::Deref for SharedState { + type Target = Arc>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct SharedProtoData { + pub fds: Option, +} diff --git a/usdpl-build/src/lib.rs b/usdpl-build/src/lib.rs new file mode 100644 index 0000000..31f742f --- /dev/null +++ b/usdpl-build/src/lib.rs @@ -0,0 +1,5 @@ +pub mod back; +pub mod front; + +mod proto_files; +pub use proto_files::{dump_protos, dump_protos_out, proto_out_path, all_proto_filenames}; diff --git a/usdpl-build/src/proto_files.rs b/usdpl-build/src/proto_files.rs new file mode 100644 index 0000000..818c728 --- /dev/null +++ b/usdpl-build/src/proto_files.rs @@ -0,0 +1,44 @@ +use std::path::{Path, PathBuf}; + +struct IncludedFileStr<'a> { + filename: &'a str, + contents: &'a str, +} + +const DEBUG_PROTO: IncludedFileStr<'static> = IncludedFileStr { + filename: "debug.proto", + contents: include_str!("../protos/debug.proto"), +}; + +const TRANSLATIONS_PROTO: IncludedFileStr<'static> = IncludedFileStr { + filename: "translations.proto", + contents: include_str!("../protos/translations.proto"), +}; + +const ALL_PROTOS: [IncludedFileStr<'static>; 2] = [ + DEBUG_PROTO, + TRANSLATIONS_PROTO, +]; + +pub fn proto_out_path() -> PathBuf { + PathBuf::from(std::env::var("OUT_DIR").expect("Not in a build.rs context (missing $OUT_DIR)")).join("protos") +} + +pub fn all_proto_filenames() -> impl Iterator { + ALL_PROTOS.iter().map(|x| x.filename) +} + +pub fn dump_protos(p: impl AsRef) -> std::io::Result<()> { + let p = p.as_ref(); + for f in ALL_PROTOS { + let fullpath = p.join(f.filename); + std::fs::write(fullpath, f.contents)?; + } + Ok(()) +} + +pub fn dump_protos_out() -> std::io::Result<()> { + let path = proto_out_path(); + std::fs::create_dir_all(&path)?; + dump_protos(&path) +} diff --git a/usdpl-core/Cargo.toml b/usdpl-core/Cargo.toml index 5efa156..b196650 100644 --- a/usdpl-core/Cargo.toml +++ b/usdpl-core/Cargo.toml @@ -1,22 +1,21 @@ [package] name = "usdpl-core" -version = "0.10.0" +version = "0.11.0" edition = "2021" license = "GPL-3.0-only" repository = "https://github.com/NGnius/usdpl-rs" -readme = "README.md" +readme = "../README.md" description = "Universal Steam Deck Plugin Library core" [features] default = [] decky = [] -crankshaft = [] encrypt = ["aes-gcm-siv"] -translate = [] [dependencies] base64 = "0.13" aes-gcm-siv = { version = "0.10", optional = true, default-features = false, features = ["alloc", "aes"] } +# nrpc = "0.2" [dev-dependencies] hex-literal = "0.3.4" diff --git a/usdpl-core/src/api_common/target.rs b/usdpl-core/src/api_common/target.rs index ed7f3ca..d34e502 100644 --- a/usdpl-core/src/api_common/target.rs +++ b/usdpl-core/src/api_common/target.rs @@ -4,8 +4,6 @@ pub enum Platform { Any, /// Decky aka PluginLoader platform Decky, - /// Crankshaft platform - Crankshaft, } impl Platform { @@ -16,10 +14,6 @@ impl Platform { { Self::Decky } - #[cfg(all(feature = "crankshaft", not(any(feature = "decky"))))] - { - Self::Crankshaft - } #[cfg(not(any(feature = "decky", feature = "crankshaft")))] { Self::Any @@ -32,7 +26,6 @@ impl std::fmt::Display for Platform { match self { Self::Any => write!(f, "any"), Self::Decky => write!(f, "decky"), - Self::Crankshaft => write!(f, "crankshaft"), } } } diff --git a/usdpl-core/src/api_crankshaft/mod.rs b/usdpl-core/src/api_crankshaft/mod.rs deleted file mode 100644 index 8b13789..0000000 --- a/usdpl-core/src/api_crankshaft/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/usdpl-core/src/socket.rs b/usdpl-core/src/socket.rs index 5a28762..0f72a01 100644 --- a/usdpl-core/src/socket.rs +++ b/usdpl-core/src/socket.rs @@ -40,10 +40,8 @@ pub enum Packet { /// Many packets merged into one Many(Vec), /// Translation data dump - #[cfg(feature = "translate")] Translations(Vec<(String, Vec)>), /// Request translations for language - #[cfg(feature = "translate")] Language(String), } @@ -59,9 +57,7 @@ impl Packet { Self::Unsupported => 6, Self::Bad => 7, Self::Many(_) => 8, - #[cfg(feature = "translate")] Self::Translations(_) => 9, - #[cfg(feature = "translate")] Self::Language(_) => 10, } } @@ -93,12 +89,10 @@ impl Loadable for Packet { let (obj, len) = <_>::load(buf)?; (Self::Many(obj), len) }, - #[cfg(feature = "translate")] 9 => { let (obj, len) = <_>::load(buf)?; (Self::Translations(obj), len) }, - #[cfg(feature = "translate")] 10 => { let (obj, len) = <_>::load(buf)?; (Self::Language(obj), len) @@ -122,9 +116,7 @@ impl Dumpable for Packet { Self::Unsupported => Ok(0), Self::Bad => return Err(DumpError::Unsupported), Self::Many(v) => v.dump(buf), - #[cfg(feature = "translate")] Self::Translations(tr) => tr.dump(buf), - #[cfg(feature = "translate")] Self::Language(l) => l.dump(buf), }?; Ok(size1 + result) diff --git a/usdpl-front/Cargo.toml b/usdpl-front/Cargo.toml index 81b42da..eaea0ef 100644 --- a/usdpl-front/Cargo.toml +++ b/usdpl-front/Cargo.toml @@ -1,27 +1,27 @@ [package] name = "usdpl-front" -version = "0.10.1" +version = "0.11.0" authors = ["NGnius (Graham) "] edition = "2021" license = "GPL-3.0-only" repository = "https://github.com/NGnius/usdpl-rs" -readme = "README.md" +readme = "../README.md" description = "Universal Steam Deck Plugin Library front-end designed for WASM" [lib] crate-type = ["cdylib", "rlib"] [features] -default = ["translate"] +default = [] decky = ["usdpl-core/decky"] -crankshaft = ["usdpl-core/crankshaft"] debug = ["console_error_panic_hook"] encrypt = ["usdpl-core/encrypt", "obfstr", "hex"] -translate = ["usdpl-core/translate"] [dependencies] wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" +gloo-net = { version = "0.2", features = ["websocket"] } +futures = "0.3" # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires @@ -39,10 +39,17 @@ web-sys = { version = "0.3", features = [ ]} js-sys = { version = "0.3" } +async-channel = "1.8" + obfstr = { version = "0.3", optional = true } hex = { version = "0.4", optional = true } -usdpl-core = { version = "0.10", path = "../usdpl-core" } +nrpc = "0.2" +usdpl-core = { version = "0.11", path = "../usdpl-core" } +prost = "0.11" [dev-dependencies] wasm-bindgen-test = { version = "0.3.13" } + +[build-dependencies] +usdpl-build = { version = "0.11", path = "../usdpl-build" } diff --git a/usdpl-front/build.rs b/usdpl-front/build.rs new file mode 100644 index 0000000..16e4f14 --- /dev/null +++ b/usdpl-front/build.rs @@ -0,0 +1,3 @@ +fn main() { + usdpl_build::front::build() +} diff --git a/usdpl-front/src/client_handler.rs b/usdpl-front/src/client_handler.rs new file mode 100644 index 0000000..d123128 --- /dev/null +++ b/usdpl-front/src/client_handler.rs @@ -0,0 +1,81 @@ +use std::sync::atomic::{AtomicU64, Ordering}; + +use nrpc::{ClientHandler, ServiceError, _helpers::bytes, _helpers::async_trait}; +use gloo_net::websocket::{Message, futures::WebSocket}; +use wasm_bindgen_futures::spawn_local; +use futures::{SinkExt, StreamExt}; + +static LAST_ID: AtomicU64 = AtomicU64::new(0); + +pub struct WebSocketHandler { + // TODO + port: u16, +} + +async fn send_recv_ws(url: String, input: bytes::Bytes) -> Result, String> { + let mut ws = WebSocket::open(&url).map_err(|e| e.to_string())?; + ws.send(Message::Bytes(input.into())).await.map_err(|e| e.to_string())?; + + read_next_incoming(ws).await +} + +async fn read_next_incoming(mut ws: WebSocket) -> Result, String> { + if let Some(msg) = ws.next().await { + match msg.map_err(|e| e.to_string())? { + Message::Bytes(b) => Ok(b), + Message::Text(_) => Err("Message::Text not allowed".into()), + } + } else { + Err("No response received".into()) + } +} + +#[derive(Debug)] +struct ErrorStr(String); + +impl std::fmt::Display for ErrorStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Error message: {}", self.0) + } +} + +impl std::error::Error for ErrorStr {} + +impl WebSocketHandler { + #[allow(dead_code)] + pub fn new(port: u16) -> Self { + Self { port } + } +} + +#[async_trait::async_trait] +impl ClientHandler for WebSocketHandler { + async fn call(&mut self, + service: &str, + method: &str, + input: bytes::Bytes, + output: &mut bytes::BytesMut) -> Result<(), ServiceError> { + let id = LAST_ID.fetch_add(1, Ordering::SeqCst); + let url = format!( + "ws://usdpl-ws-{}.localhost:{}/{}/{}", + id, + self.port, + service, + method, + ); + let (tx, rx) = async_channel::bounded(1); + spawn_local(async move { + tx.send(send_recv_ws( + url, + input + ).await).await.unwrap_or(()); + }); + + output.extend_from_slice( + &rx.recv().await + .map_err(|e| ServiceError::Method(Box::new(e)))? + .map_err(|e| ServiceError::Method(Box::new(ErrorStr(e))))? + ); + Ok(()) + } +} diff --git a/usdpl-front/src/lib.rs b/usdpl-front/src/lib.rs index 3516977..dd173f2 100644 --- a/usdpl-front/src/lib.rs +++ b/usdpl-front/src/lib.rs @@ -5,10 +5,16 @@ //! #![warn(missing_docs)] +mod client_handler; mod connection; mod convert; mod imports; +#[allow(missing_docs)] // existence is pain otherwise +pub mod _nrpc_js_interop { + include!(concat!(env!("OUT_DIR"), "/usdpl.rs")); +} + use std::sync::atomic::{AtomicU64, Ordering}; use js_sys::Array; @@ -19,7 +25,7 @@ use usdpl_core::{socket::Packet, RemoteCall}; //const REMOTE_PORT: std::sync::atomic::AtomicU16 = std::sync::atomic::AtomicU16::new(31337); static mut CTX: UsdplContext = UsdplContext { - port: 31337, + port: 0, id: AtomicU64::new(0), #[cfg(feature = "encrypt")] key: Vec::new(), @@ -27,7 +33,6 @@ static mut CTX: UsdplContext = UsdplContext { static mut CACHE: Option> = None; -#[cfg(feature = "translate")] static mut TRANSLATIONS: Option>> = None; #[cfg(feature = "encrypt")]