From 46aff0c61bb9c78d89701baca0eb2b43cae134a0 Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Sat, 17 Dec 2022 17:11:28 +0100 Subject: [PATCH] Finish implementation of new Rust Tokio Target --- examples/Rust/.gitignore | 3 +- examples/Rust/Client/Cargo.lock | 589 +++++++++++++++++++++++++++++++ examples/Rust/Client/Cargo.toml | 10 + examples/Rust/Client/src/main.rs | 52 +++ examples/Rust/Impl/Cargo.lock | 248 ------------- examples/Rust/Impl/Cargo.toml | 7 - examples/Rust/Impl/src/main.rs | 52 --- examples/Rust/Server/Cargo.lock | 589 +++++++++++++++++++++++++++++++ examples/Rust/Server/Cargo.toml | 10 + examples/Rust/Server/src/main.rs | 75 ++++ examples/Typescript/server.ts | 24 +- examples/example.jrpc | 11 + examples/test.jrpc | 14 - package.json | 2 +- src/targets/rust.ts | 74 ++-- templates/Rust/.editorconfig | 2 + templates/Rust/Cargo.toml | 13 +- templates/Rust/src/lib.rs | 447 ++++++++++------------- templates/Rust2.0/.gitignore | 2 - templates/Rust2.0/Cargo.toml | 15 - templates/Rust2.0/src/lib.rs | 44 --- 21 files changed, 1598 insertions(+), 685 deletions(-) create mode 100644 examples/Rust/Client/Cargo.lock create mode 100644 examples/Rust/Client/Cargo.toml create mode 100644 examples/Rust/Client/src/main.rs delete mode 100644 examples/Rust/Impl/Cargo.lock delete mode 100644 examples/Rust/Impl/Cargo.toml delete mode 100644 examples/Rust/Impl/src/main.rs create mode 100644 examples/Rust/Server/Cargo.lock create mode 100644 examples/Rust/Server/Cargo.toml create mode 100644 examples/Rust/Server/src/main.rs delete mode 100644 examples/test.jrpc create mode 100644 templates/Rust/.editorconfig delete mode 100644 templates/Rust2.0/.gitignore delete mode 100644 templates/Rust2.0/Cargo.toml delete mode 100644 templates/Rust2.0/src/lib.rs diff --git a/examples/Rust/.gitignore b/examples/Rust/.gitignore index ddc70ca..622cb74 100644 --- a/examples/Rust/.gitignore +++ b/examples/Rust/.gitignore @@ -1,2 +1,3 @@ Generated/ -Impl/target +Server/target +Client/target diff --git a/examples/Rust/Client/Cargo.lock b/examples/Rust/Client/Cargo.lock new file mode 100644 index 0000000..4050373 --- /dev/null +++ b/examples/Rust/Client/Cargo.lock @@ -0,0 +1,589 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "async-trait" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "example" +version = "0.1.0" +dependencies = [ + "async-trait", + "int-enum", + "log", + "nanoid", + "serde", + "serde_json", + "simple_logger", + "tokio", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "int-enum" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff87d3cc4b79b4559e3c75068d64247284aceb6a038bd4bb38387f3f164476d" +dependencies = [ + "int-enum-impl", +] + +[[package]] +name = "int-enum-impl" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1f2f068675add1a3fc77f5f5ab2e29290c841ee34d151abc007bce902e5d34" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[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.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[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 = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "simple_logger" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e190a521c2044948158666916d9e872cbb9984f755e9bb3b5b75a836205affcd" +dependencies = [ + "atty", + "colored", + "log", + "time", + "windows-sys", +] + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-impl-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "example", + "serde_json", + "tokio", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tokio" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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.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_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/examples/Rust/Client/Cargo.toml b/examples/Rust/Client/Cargo.toml new file mode 100644 index 0000000..0f29e46 --- /dev/null +++ b/examples/Rust/Client/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-impl-client" +version = "0.1.0" +edition = "2021" + +[dependencies] +example = { path = "../Generated/" } +async-trait = "0.1.59" +tokio = { version = "1.22.0", features = ["full"] } +serde_json = "1.0.88" diff --git a/examples/Rust/Client/src/main.rs b/examples/Rust/Client/src/main.rs new file mode 100644 index 0000000..78fbfec --- /dev/null +++ b/examples/Rust/Client/src/main.rs @@ -0,0 +1,52 @@ +use std::sync::atomic::AtomicU64; +use std::sync::Arc; + +use example::client::SimpleTestService; +use example::JRPCClient; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::net::TcpStream; +use tokio::sync::mpsc::channel; + +#[tokio::main] +pub async fn main() { + let (tx, mut rx) = channel(1); + let stream = TcpStream::connect("127.0.0.1:4321").await.unwrap(); + let client = example::JRPCClient::new(tx.clone()); + let test_service = SimpleTestService::new(client.clone()); + + let (reader, mut writer) = stream.into_split(); + let mut reader = BufReader::new(reader); + let mut line = String::new(); + + tokio::spawn(async move { + loop { + line.clear(); + reader.read_line(&mut line).await.unwrap(); + client.on_result(serde_json::from_str(&line).unwrap()).await; + } + }); + + tokio::spawn(async move { + while let Some(message) = rx.recv().await { + writer + .write_all((serde_json::to_string(&message).unwrap() + "\n").as_bytes()) + .await + .unwrap(); + } + }); + + let ticks = Arc::new(AtomicU64::new(0)); + let t2 = ticks.clone(); + tokio::spawn(async move { + loop { + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + println!("Ticks: {}", t2.load(std::sync::atomic::Ordering::Relaxed)); + t2.store(0, std::sync::atomic::Ordering::Relaxed); + } + }); + + loop { + let _result = test_service.GetTest("Hi".to_owned(), 55).await.unwrap(); + ticks.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + } +} diff --git a/examples/Rust/Impl/Cargo.lock b/examples/Rust/Impl/Cargo.lock deleted file mode 100644 index 1c995a6..0000000 --- a/examples/Rust/Impl/Cargo.lock +++ /dev/null @@ -1,248 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "getrandom" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "int-enum" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b1428b2b1abe959e6eedb0a17d0ab12f6ba20e1106cc29fc4874e3ba393c177" -dependencies = [ - "cfg-if 0.1.10", - "int-enum-impl", -] - -[[package]] -name = "int-enum-impl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c3cecaad8ca1a5020843500c696de2b9a07b63b624ddeef91f85f9bafb3671" -dependencies = [ - "cfg-if 0.1.10", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "libc" -version = "0.2.123" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" - -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro2" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "test" -version = "0.1.0" -dependencies = [ - "int-enum", - "nanoid", - "serde", - "serde_json", - "threadpool", -] - -[[package]] -name = "test-impl" -version = "0.1.0" -dependencies = [ - "test", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "toml" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/examples/Rust/Impl/Cargo.toml b/examples/Rust/Impl/Cargo.toml deleted file mode 100644 index cf31f2c..0000000 --- a/examples/Rust/Impl/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "test-impl" -version = "0.1.0" -edition = "2021" - -[dependencies] -test = { path = "../Generated/" } diff --git a/examples/Rust/Impl/src/main.rs b/examples/Rust/Impl/src/main.rs deleted file mode 100644 index 02a1e23..0000000 --- a/examples/Rust/Impl/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -use test::{JRPCServer,Result,Test}; -use test::server::{TestService,TestServiceHandler}; -use std::io::{BufReader,BufRead,Write}; -use std::sync::mpsc::channel; - -#[derive(Clone, Copy)] -struct MyCtx {} - -struct TestServiceImplementation {} - -impl TestService for TestServiceImplementation { - fn GetTest(&self, name: String, age: i64, _context: &MyCtx) -> Result { - return Ok(Test { name, age }); - } - - fn TestNot(&self, _: &MyCtx) -> Result<()> { - return Ok(()); - } -} - -pub fn main() { - let mut srv = JRPCServer::::new(); - srv.add_service(TestServiceHandler::new(Box::from(TestServiceImplementation {}))); - - let listener = std::net::TcpListener::bind("127.0.0.1:4321").expect("Could not start listener!"); - - for stream in listener.incoming() { - println!("Got Connection!"); - let (stx, srx) = channel::(); - let (rtx, rrx) = channel::(); - - let mut stream = stream.expect("Bad stream"); - let mut r = BufReader::new(stream.try_clone().unwrap()); - let mut line = String::new(); - - srv.start_session(srx, rtx, MyCtx {}); - - - r.read_line(&mut line).expect("Could not read line!"); - println!("Got line: {}", line); - stx.send(line).expect("Could not send packet to handler!"); - println!("Sending to handler succeeded"); - let response = rrx.recv().expect("Could not get reponse from handler!"); - println!("Prepared response {}", response); - - stream.write((response + "\n").as_bytes()).expect("Could not send reponse!"); - } - - println!("Hello World"); - - // return Ok(()); -} diff --git a/examples/Rust/Server/Cargo.lock b/examples/Rust/Server/Cargo.lock new file mode 100644 index 0000000..6969fbc --- /dev/null +++ b/examples/Rust/Server/Cargo.lock @@ -0,0 +1,589 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "async-trait" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "example" +version = "0.1.0" +dependencies = [ + "async-trait", + "int-enum", + "log", + "nanoid", + "serde", + "serde_json", + "simple_logger", + "tokio", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "int-enum" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff87d3cc4b79b4559e3c75068d64247284aceb6a038bd4bb38387f3f164476d" +dependencies = [ + "int-enum-impl", +] + +[[package]] +name = "int-enum-impl" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1f2f068675add1a3fc77f5f5ab2e29290c841ee34d151abc007bce902e5d34" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[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.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[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 = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "simple_logger" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e190a521c2044948158666916d9e872cbb9984f755e9bb3b5b75a836205affcd" +dependencies = [ + "atty", + "colored", + "log", + "time", + "windows-sys", +] + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-impl" +version = "0.1.0" +dependencies = [ + "async-trait", + "example", + "serde_json", + "tokio", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tokio" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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.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_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" diff --git a/examples/Rust/Server/Cargo.toml b/examples/Rust/Server/Cargo.toml new file mode 100644 index 0000000..0296d8d --- /dev/null +++ b/examples/Rust/Server/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-impl" +version = "0.1.0" +edition = "2021" + +[dependencies] +example = { path = "../Generated/" } +async-trait = "0.1.59" +tokio = { version = "1.22.0", features = ["full"] } +serde_json = "1.0.88" diff --git a/examples/Rust/Server/src/main.rs b/examples/Rust/Server/src/main.rs new file mode 100644 index 0000000..71f255a --- /dev/null +++ b/examples/Rust/Server/src/main.rs @@ -0,0 +1,75 @@ +use async_trait::async_trait; +use example::base_lib::JRPCResult; +use example::server::{SimpleTestService, SimpleTestServiceHandler}; +use example::{JRPCServer, Result, Test2}; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; +use tokio::net::TcpStream; +use tokio::sync::mpsc::channel; + +#[derive(Clone)] +struct TestServiceImplementation {} + +#[async_trait] +impl SimpleTestService for TestServiceImplementation { + async fn GetTest(&self, name: String, age: i64) -> Result { + return Ok(Test2 { name, age }); + } + + async fn TestNot(&self) -> Result<()> { + return Ok(()); + } +} + +fn handle_connection(stream: TcpStream, server: &JRPCServer) { + let (response_sender, mut response_receiver) = channel::(1); + + let session = server.get_session(response_sender); + + let (r, mut w) = stream.into_split(); + tokio::spawn(async move { + loop { + let res = response_receiver.recv().await; + match res { + None => break, + Some(res) => w + .write_all((serde_json::to_string(&res).unwrap() + "\n").as_bytes()) + .await + .unwrap(), + } + } + }); + + tokio::spawn(async move { + let mut reader = BufReader::new(r); + loop { + let mut line = String::new(); + let res = reader.read_line(&mut line).await; + match res { + Ok(size) => { + if size > 0 { + session.handle_request(serde_json::from_str(&line).unwrap()) + } else { + break; + } + } + Err(_) => break, + } + } + }); +} + +#[tokio::main] +pub async fn main() { + let mut srv = JRPCServer::new(); + srv.add_service(SimpleTestServiceHandler::new(Box::from( + TestServiceImplementation {}, + ))); + + let listener = tokio::net::TcpListener::bind("0.0.0.0:4321").await.unwrap(); + + loop { + let (stream, address) = listener.accept().await.unwrap(); + println!("Got connection from {}", address); + handle_connection(stream, &srv); + } +} diff --git a/examples/Typescript/server.ts b/examples/Typescript/server.ts index 0f22576..00b5b17 100644 --- a/examples/Typescript/server.ts +++ b/examples/Typescript/server.ts @@ -1,18 +1,31 @@ import * as net from "net"; -import { Server, AddValueRequest, AddValueResponse } from "./out"; +import { Server, AddValueRequest, AddValueResponse, Test2 } from "./out"; import * as readline from 'node:readline'; const server = new Server.ServiceProvider(); +class SimpleTestService extends Server.SimpleTestService { + async GetTest(name: string, age: number, ctx: undefined): Promise { + return { + name, + age, + }; + } + TestNot(ctx: undefined): void { + + } +} + + class TestService extends Server.TestService { async AddValuesSingleParam( request: AddValueRequest, ctx: undefined ): Promise { return { - value: request.value1 + request!.value2, + value: request.value1! + request!.value2!, }; } async AddValuesMultipleParams( @@ -41,6 +54,7 @@ class TestService extends Server.TestService { } server.addService(new TestService()); +server.addService(new SimpleTestService()); net.createServer((socket) => { socket.on("error", console.error); @@ -57,6 +71,6 @@ net.createServer((socket) => { sess.onMessage(JSON.parse(line)); }) rl.on("error", console.error); -}).listen(8859).on("listening", () => { - console.log("Is listening on :8859"); -}).on("error", console.error) \ No newline at end of file +}).listen(4321).on("listening", () => { + console.log("Is listening on :4321"); +}).on("error", console.error) diff --git a/examples/example.jrpc b/examples/example.jrpc index 8b259a0..ca6ec4e 100644 --- a/examples/example.jrpc +++ b/examples/example.jrpc @@ -53,3 +53,14 @@ service TestService { FunctionWithArrayAsParamAndReturn(values1: float[], values2: float[]): float[]; } + +type Test2 { + name: string; + age: int; +} + +service SimpleTestService { + @Description("asdasdasd") + GetTest(name: string, age: int): Test2; + notification TestNot(); +} diff --git a/examples/test.jrpc b/examples/test.jrpc deleted file mode 100644 index af947c5..0000000 --- a/examples/test.jrpc +++ /dev/null @@ -1,14 +0,0 @@ -define rust_crate test; - -type Test { - name: string; - age: int; -} - -service TestService { - @Description("asdasdasd") - GetTest(name: string, age: int): Test; - notification TestNot(); -} - -// { "jsonrpc": "2.0", "method": "TestService.GetTest", "params": [ "SomeName", 25 ], "id": "someid" } diff --git a/package.json b/package.json index 1d67bb5..66b82ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hibas123/jrpcgen", - "version": "1.1.6", + "version": "1.2.0", "main": "lib/index.js", "license": "MIT", "packageManager": "yarn@3.1.1", diff --git a/src/targets/rust.ts b/src/targets/rust.ts index 3d8cd4b..622eb12 100644 --- a/src/targets/rust.ts +++ b/src/targets/rust.ts @@ -122,7 +122,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { this.addDependencies(a, definition); - a(0, `use crate::base_lib::{JRPCClient,JRPCRequest,Result};`); + a(0, `use crate::base_lib::{JRPCClient, JRPCRequest, Result};`); a(0, `use serde_json::{json};`); a(0, ``); a(0, `pub struct ${definition.name}{`); @@ -142,7 +142,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { let ret = fnc.return ? typeToRust(fnc.return.type, fnc.return.array) : "()"; - a(1, `pub fn ${fnc.name}(&self, ${params}) -> Result<${ret}> {`); + a(1, `pub async fn ${fnc.name}(&self, ${params}) -> Result<${ret}> {`); a(2, `let l_req = JRPCRequest {`); a(3, `jsonrpc: "2.0".to_owned(),`); a(3, `id: None, // 'id' will be set by the send_request function`); @@ -151,21 +151,25 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { a(2, `};`); a(2, ``); if (fnc.return) { - a(2, `let l_res = self.client.send_request(l_req);`); - a(2, `if let Err(e) = l_res {`); - a(3, `return Err(e);`); - a(2, `} else if let Ok(o) = l_res {`); + a(2, `let l_res = self.client.send_request(l_req).await;`); + a(2, `match l_res {`); + a(3, `Err(e) => return Err(e),`); if (fnc.return.type == "void") { - a(3, `return ();`); + a(3, `Ok(_) => {`); + a(4, `return Ok(());`); + a(3, `}`); } else { + a(3, `Ok(o) => {`); a( - 3, + 4, `return serde_json::from_value(o).map_err(|e| Box::from(e));` ); + a(3, `}`); } - a(2, `} else { panic!("What else cases could there be?"); }`); + a(2, `}`); + } else { - a(2, `self.client.send_notification(l_req);`); + a(2, `self.client.send_notification(l_req).await;`); a(2, `return Ok(());`); } a(1, `}`); @@ -180,61 +184,62 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { const { a, getResult } = LineAppender(); this.addDependencies(a, definition); - a(0, `use crate::base_lib::{JRPCServiceHandler,JRPCRequest,Result};`); + a(0, `use crate::base_lib::{JRPCServerService, JRPCRequest, Result};`); a(0, `use serde_json::{Value};`); + a(0, `use std::sync::Arc;`); + a(0, `use async_trait::async_trait;`); const typeToRust = (type: string, array: boolean) => { let rt = toRustType(type); return array ? `Vec<${rt}>` : rt; }; - const CTX_TYPE = "'static + Sync + Send + Copy"; - - a(0, ``); - a(0, `pub trait ${definition.name} {`); + a(0, `#[async_trait]`); + a(0, `pub trait ${definition.name} {`); for (const fnc of definition.functions) { let params = fnc.inputs.length > 0 ? fnc.inputs - .map((i) => i.name + ": " + typeToRust(i.type, i.array)) - .join(", ") + ", " + .map((i) => i.name + ": " + typeToRust(i.type, i.array)) + .join(", ") : ""; let ret = fnc.return ? typeToRust(fnc.return.type, fnc.return.array) : "()"; - a(1, `fn ${fnc.name}(&self, ${params}context: &C) -> Result<${ret}>;`); + a(1, `async fn ${fnc.name}(&self, ${params}) -> Result<${ret}>;`); } a(0, `}`); a(0, ``); - a(0, `pub struct ${definition.name}Handler {`); - a(1, `implementation: Box + Sync + Send>,`); + a(0, `pub struct ${definition.name}Handler {`); + a(1, `implementation: Box,`); a(0, `}`); a(0, ``); - a(0, `impl ${definition.name}Handler {`); + a(0, `impl ${definition.name}Handler {`); a( 1, - `pub fn new(implementation: Box + Sync + Send>) -> Box {` + `pub fn new(implementation: Box) -> Arc {` ); - a(2, `return Box::from(Self { implementation });`); + a(2, `return Arc::from(Self { implementation });`); a(1, `}`); a(0, `}`); a(0, ``); + a(0, `#[async_trait]`); a( 0, - `impl JRPCServiceHandler for ${definition.name}Handler {` + `impl JRPCServerService for ${definition.name}Handler {` ); - a(1, `fn get_name(&self) -> String { "${definition.name}".to_owned() }`); + a(1, `fn get_id(&self) -> String { "${definition.name}".to_owned() }`); a(0, ``); a( 1, - `fn on_message(&self, msg: JRPCRequest, function: String, ctx: &C) -> Result<(bool, Value)> {` + `async fn handle(&self, msg: &JRPCRequest, function: &str) -> Result<(bool, Value)> {` ); - a(2, `match function.as_str() {`); + a(2, `match function {`); for (const fnc of definition.functions) { a(3, `"${fnc.name}" => {`); a(4, `if msg.params.is_array() {`); @@ -250,10 +255,10 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { a(6, `serde_json::from_value(arr[${i}].clone())`); a( 7, - `.map_err(|_| "Parameter for field '${inp.name}' should be of type '${inp.type}'!")?,` //TODO: Array + `.map_err(|_| "Parameter for field '${inp.name}' should be of type '${inp.type}'!")?${i == fnc.inputs.length - 1 ? "" : ","}` //TODO: Array ); } - a(5, `ctx)?;`); + a(5, `).await?;`); if (fnc.return) { a(5, `return Ok((true, serde_json::to_value(res)?));`); } else { @@ -296,7 +301,7 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { const as = ls.a; a(0, `pub mod base_lib;`); - a(0, `pub use base_lib::{JRPCServer,Result};`); + a(0, `pub use base_lib::{JRPCServer, JRPCClient, Result};`); for (const [typ, def] of steps) { if (typ == "type" || typ == "enum") { @@ -306,19 +311,18 @@ export class RustTarget extends CompileTarget<{ rust_crate: string }> { as(0, `mod ${toSnake(def.name)};`); as( 0, - `pub use ${toSnake(def.name)}::{${def.name}, ${ - def.name + `pub use ${toSnake(def.name)}::{${def.name}, ${def.name }Handler};` ); ac(0, `mod ${toSnake(def.name)};`); ac(0, `pub use ${toSnake(def.name)}::${def.name};`); - - a(0, `pub mod server;`); - a(0, `pub mod client;`); } } + a(0, `pub mod server;`); + a(0, `pub mod client;`); + this.writeFile(`src/lib.rs`, getResult()); this.writeFile(`src/server/mod.rs`, ls.getResult()); this.writeFile(`src/client/mod.rs`, lc.getResult()); diff --git a/templates/Rust/.editorconfig b/templates/Rust/.editorconfig new file mode 100644 index 0000000..1c9705c --- /dev/null +++ b/templates/Rust/.editorconfig @@ -0,0 +1,2 @@ +[*.rs] +indent_size = 4 diff --git a/templates/Rust/Cargo.toml b/templates/Rust/Cargo.toml index dde49f3..a4551e2 100644 --- a/templates/Rust/Cargo.toml +++ b/templates/Rust/Cargo.toml @@ -6,10 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -int-enum = "0.4.0" -serde = { version = "1.0.136", features = ["derive"] } -serde_json = "1.0.79" -threadpool = "1.8.1" +int-enum = "0.5.0" +serde = { version = "1.0.147", features = ["derive"] } +serde_json = "1.0.88" nanoid = "0.4.0" - - +tokio = { version = "1.22.0", features = ["full"] } +log = "0.4.17" +simple_logger = { version = "4.0.0", features = ["threads", "colored", "timestamps", "stderr"] } +async-trait = "0.1.59" diff --git a/templates/Rust/src/lib.rs b/templates/Rust/src/lib.rs index 5754855..59b1839 100644 --- a/templates/Rust/src/lib.rs +++ b/templates/Rust/src/lib.rs @@ -1,286 +1,223 @@ +use log::{info, trace, warn}; use nanoid::nanoid; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::boxed::Box; -use std::collections::HashMap; use std::error::Error; -use std::marker::PhantomData; use std::marker::Send; -use std::sync::mpsc::{Receiver, Sender}; -use std::sync::{Arc, Mutex}; -use threadpool::ThreadPool; +use std::{collections::HashMap, sync::Arc}; +use tokio::sync::{mpsc::Sender, Mutex}; -pub type Result = std::result::Result>; +pub type Result = std::result::Result>; -// TODO: Check what happens when error code is not included -// #[repr(i64)] -// #[derive(Clone, Copy, Debug, Eq, PartialEq, IntEnum, Deserialize, Serialize)] -// pub enum ErrorCodes { -// ParseError = -32700, -// InvalidRequest = -32600, -// MethodNotFound = -32601, -// InvalidParams = -32602, -// InternalError = -32603, -// } - -#[derive(Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct JRPCRequest { - pub jsonrpc: String, - pub id: Option, - pub method: String, - pub params: Value, + pub jsonrpc: String, + pub id: Option, + pub method: String, + pub params: Value, } -#[derive(Serialize, Deserialize)] +impl JRPCRequest { + pub fn new_request(method: String, params: Value) -> JRPCRequest { + JRPCRequest { + jsonrpc: "2.0".to_string(), + id: None, + method, + params, + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct JRPCError { - pub code: i64, - pub message: String, - pub data: Value, + pub code: i64, + pub message: String, + pub data: Value, } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct JRPCResult { - pub jsonrpc: String, - pub id: String, - pub result: Value, - pub error: Option, + pub jsonrpc: String, + pub id: String, + pub result: Value, + pub error: Option, } -// ****************************************************************************** -// * SERVER -// ****************************************************************************** - -pub trait JRPCServiceHandler: Send { - fn get_name(&self) -> String; - fn on_message(&self, msg: JRPCRequest, function: String, ctx: &C) -> Result<(bool, Value)>; -} - -type Shared = Arc>; -type SharedHM = Shared>; -type ServiceSharedHM = SharedHM>>; - -type SharedThreadPool = Shared; - -pub struct JRPCServer { - services: ServiceSharedHM, - pool: SharedThreadPool, -} - -impl JRPCServer { - pub fn new() -> Self { - return Self { - services: Arc::new(Mutex::new(HashMap::new())), - pool: Arc::new(Mutex::new(ThreadPool::new(32))), - }; - } - - pub fn add_service(&mut self, service: Box>) { - let mut services = self.services.lock().unwrap(); - services.insert(service.get_name(), service); - } - - pub fn start_session( - &mut self, - read_ch: Receiver, - write_ch: Sender, - context: CTX, - ) { - let services = self.services.clone(); - let p = self.pool.lock().unwrap(); - let pool = self.pool.clone(); - p.execute(move || { - JRPCSession::start(read_ch, write_ch, context, services, pool); - }); - } -} - -pub struct JRPCSession { - _ctx: PhantomData, -} - -unsafe impl Sync for JRPCSession {} - -impl JRPCSession { - fn start( - read_ch: Receiver, - write_ch: Sender, - context: CTX, - services: ServiceSharedHM, - pool: SharedThreadPool, - ) { - loop { - let pkg = read_ch.recv(); - let data = match pkg { - Err(_) => return, - Ok(res) => res, - }; - if data.len() == 0 { - //TODO: This can be done better - return; - } - let ctx = context.clone(); - let svs = services.clone(); - let wc = write_ch.clone(); - pool.lock().unwrap().execute(move || { - JRPCSession::handle_packet(data, wc, ctx, svs); - }) - } - } - - fn handle_packet( - data: String, - write_ch: Sender, - context: CTX, - services: ServiceSharedHM, - ) { - let req: Result = - serde_json::from_str(data.as_str()).map_err(|err| Box::from(err)); - - let req = match req { - Err(_) => { - return; - } - Ok(parsed) => parsed, - }; - - let req_id = req.id.clone(); - - let mut parts: Vec = req.method.splitn(2, '.').map(|e| e.to_owned()).collect(); - if parts.len() != 2 { - return Self::send_err_res(req_id, write_ch, Box::from("Error".to_owned())); - } - - let service = parts.remove(0); - let function = parts.remove(0); - - let svs = services.lock().unwrap(); - let srv = svs.get(&service); - - if let Some(srv) = srv { - match srv.on_message(req, function, &context) { - Ok((is_send, value)) => { - if is_send { - if let Some(id) = req_id { - let r = JRPCResult { - jsonrpc: "2.0".to_owned(), - id, - result: value, - error: None, - }; - let s = serde_json::to_string(&r); - if s.is_ok() { - write_ch - .send(s.unwrap()) - .expect("Sending data into channel failed!"); - } - } - } - } - Err(err) => return Self::send_err_res(req_id, write_ch, err), - } - } - } - - fn send_err_res(id: Option, write_ch: Sender, err: Box) { - if let Some(id) = id { - let error = JRPCError { - code: 0, //TODO: Make this better? - message: err.to_string(), - data: Value::Null, - }; - - let r = JRPCResult { - jsonrpc: "2.0".to_owned(), - id: id.clone(), - result: Value::Null, - error: Option::from(error), - }; - - let s = serde_json::to_string(&r); - - if s.is_ok() { - write_ch - .send(s.unwrap()) - .expect("Sending data into channel failed!"); - } - } - - return (); - } -} - -// ****************************************************************************** -// * CLIENT -// ****************************************************************************** - -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct JRPCClient { - write_ch: Sender, - requests: SharedHM>>, + message_sender: Sender, + requests: Arc>>>, } -unsafe impl Send for JRPCClient {} //TODO: Is this a problem - impl JRPCClient { - pub fn new(write_ch: Sender, read_ch: Receiver) -> Self { - let n = Self { - write_ch, - requests: Arc::new(Mutex::new(HashMap::new())), - }; + pub fn new(sender: Sender) -> JRPCClient { + JRPCClient { + message_sender: sender, + requests: Arc::new(Mutex::new(HashMap::new())), + } + } - n.start(read_ch); - return n; - } + pub async fn send_request(&self, mut request: JRPCRequest) -> Result { + let (sender, mut receiver) = tokio::sync::mpsc::channel(1); - pub fn start(&self, read_ch: Receiver) { - let s = self.clone(); - std::thread::spawn(move || { - s.start_reader(read_ch); - }); - } + if request.id.is_none() { + request.id = Some(nanoid!()); + } - fn start_reader(&self, read_ch: Receiver) { - loop { - let data = read_ch.recv().expect("Error receiving packet!"); - let response: JRPCResult = - serde_json::from_str(data.as_str()).expect("Error decoding response!"); - let id = response.id; + { + let mut self_requests = self.requests.lock().await; + self_requests.insert(request.id.clone().unwrap(), sender); + } + self.message_sender.send(request).await?; - let reqs = self.requests.lock().expect("Error locking requests map!"); - let req = reqs.get(&id); - if let Some(req) = req { - let res = if let Some(err) = response.error { - Err(Box::from(err.message)) + let result = receiver.recv().await; + + if let Some(result) = result { + if let Some(error) = result.error { + return Err(format!("Error while receiving result: {}", error.message).into()); } else { - Ok(response.result) + return Ok(result.result); + } + } else { + return Err("Error while receiving result".into()); + } + } + + pub async fn send_notification(&self, mut request: JRPCRequest) { + request.id = None; + + _ = self.message_sender.send(request).await; + } + + pub async fn on_result(&self, result: JRPCResult) { + let id = result.id.clone(); + let mut self_requests = self.requests.lock().await; + let sender = self_requests.get(&id); + if let Some(sender) = sender { + _ = sender.send(result).await; + self_requests.remove(&id); + } + } +} + +#[async_trait::async_trait] +pub trait JRPCServerService: Send + Sync + 'static { + fn get_id(&self) -> String; + async fn handle(&self, request: &JRPCRequest, function: &str) -> Result<(bool, Value)>; +} + +pub type JRPCServiceHandle = Arc; + +#[derive(Clone)] +pub struct JRPCSession { + server: JRPCServer, + message_sender: Sender, +} + +impl JRPCSession { + pub fn new(server: JRPCServer, sender: Sender) -> JRPCSession { + JRPCSession { + server, + message_sender: sender, + } + } + + async fn send_error(&self, request: JRPCRequest, error_msg: String, error_code: i64) -> () { + if let Some(request_id) = request.id { + let error = JRPCError { + code: error_code, + message: error_msg, + data: Value::Null, + }; + let result = JRPCResult { + jsonrpc: "2.0".to_string(), + id: request_id, + result: Value::Null, + error: Some(error), }; - req.send(res).expect("Error sending reponse!"); - } - } - } + // Send result + let result = self.message_sender.send(result).await; + if let Err(err) = result { + warn!("Error while sending result: {}", err); + } + } + } - pub fn send_request(&self, mut req: JRPCRequest) -> Result { - let mut reqs = self.requests.lock().expect("Error locking requests map!"); - let id = nanoid!(); - req.id = Some(id.clone()); + pub fn handle_request(&self, request: JRPCRequest) -> () { + let session = self.clone(); + tokio::task::spawn(async move { + info!("Received request: {}", request.method); + trace!("Request data: {:?}", request); + let method: Vec<&str> = request.method.split('.').collect(); + if method.len() != 2 { + warn!("Invalid method received: {}", request.method); + return; + } + let service = method[0]; + let function = method[1]; - let (tx, rx) = std::sync::mpsc::channel(); - - reqs.insert(id, tx); - self - .write_ch - .send(serde_json::to_string(&req).expect("Error converting Request to JSON!")) - .expect("Error Sending to Channel!"); - return rx.recv().expect("Error getting response!"); - } - - pub fn send_notification(&self, mut req: JRPCRequest) { - req.id = None; - - self - .write_ch - .send(serde_json::to_string(&req).expect("Error converting Request to JSON!")) - .expect("Error Sending to Channel!"); - } + let service = session.server.services.get(service); + if let Some(service) = service { + let result = service.handle(&request, function).await; + match result { + Ok((is_send, result)) => { + if is_send && request.id.is_some() { + let result = session + .message_sender + .send(JRPCResult { + jsonrpc: "2.0".to_string(), + id: request.id.unwrap(), + result, + error: None, + }) + .await; + if let Err(err) = result { + warn!("Error while sending result: {}", err); + } + } + } + Err(err) => { + warn!("Error while handling request: {}", err); + session + .send_error( + request, + format!("Error while handling request: {}", err), + 1, + ) + .await; + } + } + } else { + warn!("Service not found: {}", method[0]); + session + .send_error(request, "Service not found".to_string(), 1) + .await; + return; + } + }); + } +} + +#[derive(Clone)] +pub struct JRPCServer { + services: HashMap, +} + +impl JRPCServer { + pub fn new() -> JRPCServer { + JRPCServer { + services: HashMap::new(), + } + } + + pub fn add_service(&mut self, service: JRPCServiceHandle) -> () { + let id = service.get_id(); + self.services.insert(id, service); + } + + pub fn get_session(&self, sender: Sender) -> JRPCSession { + JRPCSession::new(self.clone(), sender) + } } diff --git a/templates/Rust2.0/.gitignore b/templates/Rust2.0/.gitignore deleted file mode 100644 index a9d37c5..0000000 --- a/templates/Rust2.0/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/templates/Rust2.0/Cargo.toml b/templates/Rust2.0/Cargo.toml deleted file mode 100644 index 603aa7b..0000000 --- a/templates/Rust2.0/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "__name__" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -int-enum = "0.5.0" -serde = { version = "1.0.147", features = ["derive"] } -serde_json = "1.0.88" -threadpool = "1.8.1" -nanoid = "0.4.0" -tokio = { version = "1.22.0", features = ["full"] } - diff --git a/templates/Rust2.0/src/lib.rs b/templates/Rust2.0/src/lib.rs deleted file mode 100644 index c669dc5..0000000 --- a/templates/Rust2.0/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -use nanoid::nanoid; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use std::boxed::Box; -use std::collections::HashMap; -use std::error::Error; -use std::marker::PhantomData; -use std::marker::Send; -use std::sync::mpsc::{Receiver, Sender}; -use std::sync::{Arc, Mutex}; -use threadpool::ThreadPool; - -pub type Result = std::result::Result>; - -#[derive(Serialize, Deserialize)] -pub struct JRPCRequest { - pub jsonrpc: String, - pub id: Option, - pub method: String, - pub params: Value, -} - -#[derive(Serialize, Deserialize)] -pub struct JRPCError { - pub code: i64, - pub message: String, - pub data: Value, -} - -#[derive(Serialize, Deserialize)] -pub struct JRPCResult { - pub jsonrpc: String, - pub id: String, - pub result: Value, - pub error: Option, -} - -struct JRPCServer {} - -impl JRPCServer { - fn handle(&self) -> () {} -} - -struct JRPCServerService {}