diff --git a/Cargo.lock b/Cargo.lock index 838cb5a..a718723 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "libc" version = "0.2.155" @@ -82,6 +88,16 @@ dependencies = [ "adler", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.36.0" @@ -159,7 +175,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", + "num_cpus", "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d4b49a5..5c29ab7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,8 @@ proc-macro2 = "1.0.85" quote = "1.0.36" serde = { version = "1.0.203", features = ["serde_derive"] } syn = "2.0.66" -tokio = { version = "1.38.0", features = ["sync"] } +# TODO: rt and macros should be removed unless we do tests +tokio = { version = "1.38.0", features = ["sync", "rt-multi-thread", "macros"] } [lib] proc-macro = true diff --git a/src/lib.rs b/src/lib.rs index 98a08af..331df8d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,6 +123,7 @@ fn derive_protocol(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream // Create an error and result type for sending messages let error_enum = quote! { + #[derive(Debug)] #vis enum #error_enum_name { SendError(tokio::sync::mpsc::error::SendError<(u64, #question_enum_name)>), Closed, diff --git a/tests/mod.rs b/tests/mod.rs index d9d1d7a..9b980fa 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use eagle::Protocol; +use tokio::sync::mpsc::{self, Receiver, Sender}; #[derive(Protocol)] enum TestProtocol { @@ -25,23 +26,63 @@ enum TestProtocol { Void((), ()), } -struct DummyServer; -impl TestProtocolServer for DummyServer { - fn some_kind_of_question(&mut self, question: String) -> i32 { - question.len() as i32 - } - - fn addition(&mut self, a: i32, b: i32) -> i32 { - a + b - } - - fn this_responds_with_a_string(&mut self, arg: i32) -> String { - format!("The number is {}", arg) - } - - fn void(&mut self) { - println!("Void function called!") - } +#[tokio::test] +async fn main() { + let (qtx, qrx) = mpsc::channel(16); + let (atx, arx) = mpsc::channel(16); + let mut client = TestProtocolClient::new(qtx, arx); + let server = tokio::spawn(server_loop(qrx, atx)); + let result = client.addition(2, 5).await.unwrap(); + assert_eq!(result, 7); + let result = client + .some_kind_of_question("Hello, world!".to_string()) + .await + .unwrap(); + assert_eq!(result, "Hello, world!".len() as i32); + let result = client.this_responds_with_a_string(42).await.unwrap(); + assert_eq!(result, "The number is 42"); + client.void().await.unwrap(); + server.abort(); } -fn main() {} +async fn server_loop( + mut qrx: Receiver<(u64, __TestProtocolQuestion)>, + atx: Sender<(u64, __TestProtocolAnswer)>, +) { + loop { + if let Some((nonce, q)) = qrx.recv().await { + match q { + __TestProtocolQuestion::addition((a, b)) => { + atx.send((nonce, __TestProtocolAnswer::addition(a + b))) + .await + .unwrap(); + } + __TestProtocolQuestion::some_kind_of_question(s) => { + atx.send(( + nonce, + __TestProtocolAnswer::some_kind_of_question(s.len() as i32), + )) + .await + .unwrap(); + } + __TestProtocolQuestion::this_responds_with_a_string(i) => { + atx.send(( + nonce, + __TestProtocolAnswer::this_responds_with_a_string(format!( + "The number is {}", + i + )), + )) + .await + .unwrap(); + } + __TestProtocolQuestion::void(()) => { + println!("Received void question"); + atx.send((nonce, __TestProtocolAnswer::void(()))) + .await + .unwrap(); + } + } + } + } +}