commit 56ed5b6d312d0630ef273834858c60b943925cd7 Author: NGnius (Graham) Date: Mon Apr 10 14:34:03 2023 -0400 Create MVP of nRPC codegen diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..152b00d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,838 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[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 = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +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 = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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 = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "logos" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax", + "syn 1.0.109", +] + +[[package]] +name = "miette" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.13", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nrpc" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "prost", +] + +[[package]] +name = "nrpc-build" +version = "0.1.0" +dependencies = [ + "nrpc", + "prettyplease 0.2.4", + "proc-macro2", + "prost-build", + "protox", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "nrpc-codegen-test" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "nrpc", + "nrpc-build", + "prost", + "tokio", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + +[[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-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.13", +] + +[[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 = "prost" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" +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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-reflect" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed70ac018c3e2ea5c23170a76ceb5a2874361fa3bdb3e5492f96a5c3f1153d70" +dependencies = [ + "logos", + "miette", + "once_cell", + "prost", + "prost-types", +] + +[[package]] +name = "prost-types" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88" +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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9890ddb19db578f0b160bc881eba91e1cc3775ccd40b20ddbe5e4a76ca8d591f" +dependencies = [ + "logos", + "miette", + "prost-types", + "thiserror", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +dependencies = [ + "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 = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "tokio" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..56ad1c1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = [ "nrpc", "nrpc-*" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..b8b0b78 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +[![nRPC](https://img.shields.io/crates/v/nrpc?label=nrpc&style=flat-square)](https://crates.io/crates/nrpc) +[![nRPC-build](https://img.shields.io/crates/v/nrpc-build?label=nrpc-build&style=flat-square)](https://crates.io/crates/nrpc-build) + +# nRPC + +NG's custom spin of gRPC. Intended to be decoupled from the network layer for use with websockets. diff --git a/nrpc-build/Cargo.toml b/nrpc-build/Cargo.toml new file mode 100644 index 0000000..3d9226e --- /dev/null +++ b/nrpc-build/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "nrpc-build" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# gRPC/protobuf +protox = "0.3" +prost-build = "0.11" + +# code gen +prettyplease = "0.2" +quote = "1.0" +syn = "2.0" +proc-macro2 = "1.0" + +nrpc = { version = "0.1", path = "../nrpc" } diff --git a/nrpc-build/src/builder.rs b/nrpc-build/src/builder.rs new file mode 100644 index 0000000..cb386fa --- /dev/null +++ b/nrpc-build/src/builder.rs @@ -0,0 +1,39 @@ +use std::path::Path; +use std::convert::AsRef; +use std::iter::IntoIterator; + +use prost_build::Config; + +/// Compile proto files into Rust with server and client implementations +pub fn compile( + files: impl IntoIterator>, + includes: impl IntoIterator> +) { + let file_descriptors = protox::compile(files, includes).unwrap(); + Config::new() + .service_generator(Box::new(super::ProtobufServiceGenerator::all())) + .compile_fds(file_descriptors) + .unwrap(); +} + +pub fn compile_clients( + files: impl IntoIterator>, + includes: impl IntoIterator>, +) { + let file_descriptors = protox::compile(files, includes).unwrap(); + Config::new() + .service_generator(Box::new(super::ProtobufServiceGenerator::client())) + .compile_fds(file_descriptors) + .unwrap(); +} + +pub fn compile_servers( + files: impl IntoIterator>, + includes: impl IntoIterator>, +) { + let file_descriptors = protox::compile(files, includes).unwrap(); + Config::new() + .service_generator(Box::new(super::ProtobufServiceGenerator::server())) + .compile_fds(file_descriptors) + .unwrap(); +} diff --git a/nrpc-build/src/lib.rs b/nrpc-build/src/lib.rs new file mode 100644 index 0000000..fbd70ea --- /dev/null +++ b/nrpc-build/src/lib.rs @@ -0,0 +1,5 @@ +mod builder; +mod service_gen; + +pub use builder::{compile, compile_servers, compile_clients}; +pub(crate) use service_gen::ProtobufServiceGenerator; diff --git a/nrpc-build/src/service_gen.rs b/nrpc-build/src/service_gen.rs new file mode 100644 index 0000000..040a64a --- /dev/null +++ b/nrpc-build/src/service_gen.rs @@ -0,0 +1,210 @@ +use prost_build::{Service, ServiceGenerator}; +use quote::quote; + +pub(crate) struct ProtobufServiceGenerator { + generate_server: bool, + generate_client: bool, +} + +impl ProtobufServiceGenerator { + pub fn all() -> Self { + Self { + generate_server: true, + generate_client: true, + } + } + + pub fn client() -> Self { + Self { + generate_server: false, + generate_client: true, + } + } + + pub fn server() -> Self { + Self { + generate_server: true, + generate_client: false, + } + } +} + +fn trait_methods_server(descriptors: &Vec) -> proc_macro2::TokenStream { + let mut gen_methods = Vec::with_capacity(descriptors.len()); + let mut gen_method_match_arms = Vec::with_capacity(descriptors.len()); + for descriptor in descriptors { + match (descriptor.client_streaming, descriptor.server_streaming) { + (false, false) => { // no streaming; 1->1 + let input_ty = quote::format_ident!("{}", descriptor.input_type); + let output_ty = quote::format_ident!("{}", descriptor.output_type); + let fn_name = quote::format_ident!("{}", descriptor.name); + let method_name = &descriptor.name; + gen_methods.push( + quote! { + async fn #fn_name(&mut self, input: #input_ty) -> Result<#output_ty, Box>; + } + ); + + gen_method_match_arms.push( + quote! { + #method_name => { + Ok(self.#fn_name(#input_ty::decode(payload)?).await?.encode(buffer)?) + } + } + ); + }, + (true, false) => { // client streaming; 1 -> many + todo!("streaming not supported") + }, + (false, true) => { // server streaming; many -> 1 + todo!("streaming not supported") + } + (true, true) => { // all streaming; many -> many + todo!("streaming not supported") + }, + } + + } + + quote! { + #(#gen_methods)* + + async fn call(&mut self, method: &str, payload: ::nrpc::_helpers::bytes::Bytes, buffer: &mut ::nrpc::_helpers::bytes::BytesMut) -> Result<(), ::nrpc::ServiceError> { + match method { + #(#gen_method_match_arms)* + _ => Err(::nrpc::ServiceError::MethodNotFound) + } + } + } +} + +fn struct_methods_client(service_name: &str, descriptors: &Vec) -> proc_macro2::TokenStream { + let mut gen_methods = Vec::with_capacity(descriptors.len()); + for descriptor in descriptors { + match (descriptor.client_streaming, descriptor.server_streaming) { + (false, false) => { // no streaming; 1->1 + let input_ty = quote::format_ident!("{}", descriptor.input_type); + let output_ty = quote::format_ident!("{}", descriptor.output_type); + let fn_name = quote::format_ident!("{}", descriptor.name); + let method_name = &descriptor.name; + gen_methods.push( + quote! { + pub async fn #fn_name(&mut self, input: #input_ty) -> Result<#output_ty, ::nrpc::ServiceError> { + let mut in_buf = ::nrpc::_helpers::bytes::BytesMut::new(); + input.encode(&mut in_buf)?; + let mut out_buf = ::nrpc::_helpers::bytes::BytesMut::new(); + self.inner.call(#service_name, #method_name, in_buf.into(), &mut out_buf).await?; + Ok(#output_ty::decode(out_buf)?) + } + } + ); + }, + (true, false) => { // client streaming; 1 -> many + todo!("streaming not supported") + }, + (false, true) => { // server streaming; many -> 1 + todo!("streaming not supported") + } + (true, true) => { // all streaming; many -> many + todo!("streaming not supported") + }, + } + + } + + quote! { + #(#gen_methods)* + } +} + +impl ServiceGenerator for ProtobufServiceGenerator { + fn generate(&mut self, service: Service, buf: &mut String) { + if self.generate_server { + let service_mod_name = quote::format_ident!("{}_mod_server", service.name.to_lowercase()); + let service_trait_name = quote::format_ident!("{}Service", service.name); + let service_trait_methods = trait_methods_server(&service.methods); + let service_struct_name = quote::format_ident!("{}ServiceImpl", service.name); + let descriptor_str = format!("{}.{}", service.package, service.name); + let gen_service = quote! { + mod #service_mod_name { + use super::*; + use ::nrpc::_helpers::async_trait::async_trait; + use ::nrpc::_helpers::prost::Message; + + #[async_trait] + pub trait #service_trait_name: Send { + #service_trait_methods + } + + pub struct #service_struct_name { + inner: T, + } + + impl #service_struct_name { + pub fn new(inner: T) -> Self { + Self { + inner, + } + } + } + + #[async_trait] + impl ::nrpc::ServerService for #service_struct_name { + fn descriptor(&self) -> &'static str { + #descriptor_str + } + + async fn call(&mut self, method: &str, payload: ::nrpc::_helpers::bytes::Bytes, buffer: &mut ::nrpc::_helpers::bytes::BytesMut) -> Result<(), ::nrpc::ServiceError> { + self.inner.call(method, payload, buffer).await + } + } + } + pub mod server { + pub use super::#service_mod_name::{#service_struct_name, #service_trait_name}; + } + }; + let gen_code: syn::File = syn::parse2(gen_service).expect("invalid tokenstream"); + let code_str = prettyplease::unparse(&gen_code); + buf.push_str(&code_str); + } + if self.generate_client { + let service_mod_name = quote::format_ident!("{}_mod_client", service.name.to_lowercase()); + let service_methods = struct_methods_client(&service.name, &service.methods); + let service_struct_name = quote::format_ident!("{}Service", service.name); + let descriptor_str = format!("{}.{}", service.package, service.name); + let gen_client = quote! { + mod #service_mod_name { + use super::*; + use ::nrpc::_helpers::prost::Message; + + //#[derive(core::any::Any)] + pub struct #service_struct_name { + inner: T, + } + + impl ::nrpc::ClientService for #service_struct_name { + fn descriptor(&self) -> &'static str { + #descriptor_str + } + } + + impl #service_struct_name { + pub fn new(inner: T) -> Self { + Self { + inner, + } + } + + #service_methods + } + } + pub mod client { + pub use super::#service_mod_name::#service_struct_name; + } + }; + let gen_code: syn::File = syn::parse2(gen_client).expect("invalid tokenstream"); + let code_str = prettyplease::unparse(&gen_code); + buf.push_str(&code_str); + } + } +} diff --git a/nrpc-codegen-test/Cargo.toml b/nrpc-codegen-test/Cargo.toml new file mode 100644 index 0000000..e809933 --- /dev/null +++ b/nrpc-codegen-test/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "nrpc-codegen-test" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prost = "0.11" +nrpc = { version = "0.1", path = "../nrpc" } +bytes = "1" +async-trait = "0.1" +tokio = { version = "*", features = [ "full" ] } + +[build-dependencies] +nrpc-build = { version = "0.1", path = "../nrpc-build" } diff --git a/nrpc-codegen-test/build.rs b/nrpc-codegen-test/build.rs new file mode 100644 index 0000000..3828367 --- /dev/null +++ b/nrpc-codegen-test/build.rs @@ -0,0 +1,3 @@ +fn main() { + nrpc_build::compile(["./proto/helloworld.proto"], ["."]) +} diff --git a/nrpc-codegen-test/proto/helloworld.proto b/nrpc-codegen-test/proto/helloworld.proto new file mode 100644 index 0000000..d79a6a0 --- /dev/null +++ b/nrpc-codegen-test/proto/helloworld.proto @@ -0,0 +1,37 @@ +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.examples.helloworld"; +option java_outer_classname = "HelloWorldProto"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +} diff --git a/nrpc-codegen-test/src/main.rs b/nrpc-codegen-test/src/main.rs new file mode 100644 index 0000000..4da19d9 --- /dev/null +++ b/nrpc-codegen-test/src/main.rs @@ -0,0 +1,61 @@ +use std::error::Error; + +use prost::Message; +use nrpc::ServerService; + +pub mod helloworld { + include!(concat!(env!("OUT_DIR"), "/helloworld.rs")); +} + +#[tokio::main] +async fn main() { + let req = helloworld::HelloRequest { + name: "World".into(), + }; + let resp = helloworld::HelloReply { + message: "Hello World".into(), + }; + // server + let mut service_impl = helloworld::server::GreeterServiceImpl::new(GreeterService); + let mut input_buf = bytes::BytesMut::new(); + let mut output_buf = bytes::BytesMut::new(); + req.encode(&mut input_buf).unwrap(); + service_impl.call("say_hello", input_buf.into(), &mut output_buf).await.unwrap(); + let actual_resp = helloworld::HelloReply::decode(output_buf).unwrap(); + assert_eq!(resp, actual_resp); + + // client + let mut client_impl = helloworld::client::GreeterService::new(ClientHandler); + let resp = client_impl.say_hello(req).await.unwrap(); + assert_eq!(resp, actual_resp); +} + +struct GreeterService; + +#[async_trait::async_trait] +impl helloworld::server::GreeterService for GreeterService { + async fn say_hello(&mut self, input: helloworld::HelloRequest) -> Result> { + let result = helloworld::HelloReply { + message: format!("Hello {}", input.name), + }; + println!("{}", result.message); + Ok(result) + } +} + +struct ClientHandler; + +#[async_trait::async_trait] +impl nrpc::ClientHandler for ClientHandler { + async fn call(&mut self, + service: &str, + method: &str, + input: bytes::Bytes, + output: &mut bytes::BytesMut) -> Result<(), nrpc::ServiceError> { + println!("call {}/{} with data {:?}", service, method, input); + // This is ok to hardcode ONLY because it's for testing + Ok(helloworld::HelloReply { + message: "Hello World".into(), + }.encode(output)?) + } +} diff --git a/nrpc/Cargo.toml b/nrpc/Cargo.toml new file mode 100644 index 0000000..79ffb64 --- /dev/null +++ b/nrpc/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "nrpc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prost = "0.11" +bytes = "1" +async-trait = "0.1" diff --git a/nrpc/src/lib.rs b/nrpc/src/lib.rs new file mode 100644 index 0000000..e9cefe4 --- /dev/null +++ b/nrpc/src/lib.rs @@ -0,0 +1,9 @@ +mod service; + +pub use service::{ServerService, ServiceError, ClientService, ClientHandler}; + +pub mod _helpers { + pub use async_trait; + pub use bytes; + pub use prost; +} diff --git a/nrpc/src/service.rs b/nrpc/src/service.rs new file mode 100644 index 0000000..6a4f9a6 --- /dev/null +++ b/nrpc/src/service.rs @@ -0,0 +1,63 @@ +#[async_trait::async_trait] +pub trait ServerService { + fn descriptor(&self) -> &'static str; + + async fn call(&mut self, + method: &str, + input: bytes::Bytes, + output: &mut bytes::BytesMut) -> Result<(), ServiceError>; +} + +#[async_trait::async_trait] +pub trait ClientHandler { + async fn call(&mut self, + service: &str, + method: &str, + input: bytes::Bytes, + output: &mut bytes::BytesMut) -> Result<(), ServiceError>; +} + +pub trait ClientService { + fn descriptor(&self) -> &'static str; +} + +#[derive(Debug)] +pub enum ServiceError { + Encode(prost::EncodeError), + Decode(prost::DecodeError), + MethodNotFound, + ServiceNotFound, + Method(Box), +} + +impl std::fmt::Display for ServiceError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Encode(en) => write!(f, "Encode error: {}", en), + Self::Decode(de) => write!(f, "Decode error: {}", de), + Self::MethodNotFound => write!(f, "Method not found error"), + Self::ServiceNotFound => write!(f, "Service not found error"), + Self::Method(e) => write!(f, "Method error: {}", e), + } + } +} + +impl std::convert::From for ServiceError { + fn from(value: prost::EncodeError) -> Self { + Self::Encode(value) + } +} + +impl std::convert::From for ServiceError { + fn from(value: prost::DecodeError) -> Self { + Self::Decode(value) + } +} + +impl std::convert::From> for ServiceError { + fn from(value: Box) -> Self { + Self::Method(value) + } +} + +impl std::error::Error for ServiceError {}