From 6509b6619d6d2a97da0182b06d2be3d291d63be3 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 16 Oct 2021 11:02:09 +0200 Subject: [PATCH] Add callback macro Signed-off-by: trivernis --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 108 ++++++++++++++++++++++++----------------- src/lib.rs | 59 ++++++++++++---------- src/macros.rs | 9 ++++ src/tests/ipc_tests.rs | 32 ++++++------ 6 files changed, 125 insertions(+), 87 deletions(-) create mode 100644 src/macros.rs diff --git a/Cargo.lock b/Cargo.lock index 795eed0c..8e94025e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,7 +148,7 @@ dependencies = [ [[package]] name = "rmp-ipc" -version = "0.4.3" +version = "0.4.4" dependencies = [ "lazy_static", "log", diff --git a/Cargo.toml b/Cargo.toml index 614bd7ad..d82012b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rmp-ipc" -version = "0.4.3" +version = "0.4.4" authors = ["trivernis "] edition = "2018" readme = "README.md" diff --git a/README.md b/README.md index 8520a451..415ad5d0 100644 --- a/README.md +++ b/README.md @@ -6,33 +6,45 @@ Interprocess Communication via TCP using Rust MessagePack. **Client:** ```rust -use rmp_ipc::IPCBuilder; -// create the client -let ctx = IPCBuilder::new() - .address("127.0.0.1:2020") - // register callback - .on("ping", |_ctx, _event| Box::pin(async move { - println!("Received ping event."); - Ok(()) - })) - .build_client().await.unwrap(); +use rmp_ipc::{callback, Event, context::Context, IPCBuilder, error::Result}; + +/// Callback ping function +async fn handle_ping(ctx: &Context, event: Event) -> Result<()> { + println!("Received ping event."); + ctx.emitter.emit_response(event.id(), "pong", ()).await?; + Ok(()) +} + +#[tokio::main] +async fn main() { + // create the client + let ctx = IPCBuilder::new() + .address("127.0.0.1:2020") + // register callback + .on("ping", callback!(handle_ping)) + .build_client().await.unwrap(); // emit an initial event -let response = ctx.emitter.emit("ping", ()).await?.await_response(&ctx).await?; + let response = ctx.emitter.emit("ping", ()).await?.await_response(&ctx).await?; +} ``` **Server:** ```rust -use rmp_ipc::IPCBuilder; +use rmp_ipc::{IPCBuilder, callback}; // create the server -IPCBuilder::new() - .address("127.0.0.1:2020") - // register callback - .on("ping", |_ctx, _event| Box::pin(async move { - println!("Received ping event."); - Ok(()) - })) - .build_server().await.unwrap(); + +#[tokio::main] +async fn main() { + IPCBuilder::new() + .address("127.0.0.1:2020") + // register callback + .on("ping", callback!(ctx, event, async move { + println!("Received ping event."); + Ok(()) + })) + .build_server().await.unwrap(); +} ``` ### Namespaces @@ -41,38 +53,46 @@ IPCBuilder::new() ```rust use rmp_ipc::IPCBuilder; // create the client -let ctx = IPCBuilder::new() - .address("127.0.0.1:2020") - // register namespace - .namespace("mainspace-client") - // register callback - .on("ping", |_ctx, _event| Box::pin(async move { - println!("Received ping event."); - Ok(()) - })) - .build() - .build_client().await.unwrap(); + +#[tokio::main] +async fn main() { + let ctx = IPCBuilder::new() + .address("127.0.0.1:2020") + // register namespace + .namespace("mainspace-client") + // register callback (without macro) + .on("ping", |_ctx, _event| Box::pin(async move { + println!("Received ping event."); + Ok(()) + })) + .build() + .build_client().await.unwrap(); // emit an initial event -let response = ctx.emitter.emit_to("mainspace-server", "ping", ()).await? - .await_response(&ctx).await?; + let response = ctx.emitter.emit_to("mainspace-server", "ping", ()).await? + .await_response(&ctx).await?; +} ``` **Server:** ```rust use rmp_ipc::IPCBuilder; // create the server -IPCBuilder::new() - .address("127.0.0.1:2020") - // register namespace - .namespace("mainspace-server") - // register callback - .on("ping", |_ctx, _event| Box::pin(async move { - println!("Received ping event."); - Ok(()) - })) - .build() - .build_server().await.unwrap(); + +#[tokio::main] +async fn main() { + IPCBuilder::new() + .address("127.0.0.1:2020") + // register namespace + .namespace("mainspace-server") + // register callback (without macro) + .on("ping", |_ctx, _event| Box::pin(async move { + println!("Received ping event."); + Ok(()) + })) + .build() + .build_server().await.unwrap(); +} ``` ## License diff --git a/src/lib.rs b/src/lib.rs index 06d29128..9ade86c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,37 +2,44 @@ //! messagepack. All calls are asynchronous and event based. //! Client Example: //! ```no_run -//! use rmp_ipc::IPCBuilder; -//! // create the client -//! # async fn a() { +//! use rmp_ipc::{callback, Event, context::Context, IPCBuilder, error::Result}; //! -//! let ctx = IPCBuilder::new() -//! .address("127.0.0.1:2020") -//! // register callback -//! .on("ping", |ctx, event| Box::pin(async move { -//! println!("Received ping event."); -//! ctx.emitter.emit_response(event.id(), "pong", ()).await?; -//! Ok(()) -//! })) -//! .namespace("mainspace-client") -//! .on("something", |ctx, event| Box::pin(async move { -//! println!("I think the server did something"); -//! ctx.emitter.emit_response_to(event.id(), "mainspace-server", "ok", ()).await?; -//! Ok(()) -//! })) -//! .build() -//! .build_client().await.unwrap(); +//! /// Callback ping function +//! async fn handle_ping(ctx: &Context, event: Event) -> Result<()> { +//! println!("Received ping event."); +//! ctx.emitter.emit_response(event.id(), "pong", ()).await?; //! -//! // emit an initial event -//! let response = ctx.emitter.emit("ping", ()).await.unwrap().await_reply(&ctx).await.unwrap(); -//! assert_eq!(response.name(), "pong"); -//! # } +//! Ok(()) +//! } +//! +//! #[tokio::main] +//! async fn main() { +//! // create the client +//! let ctx = IPCBuilder::new() +//! .address("127.0.0.1:2020") +//! // register callback +//! .on("ping", callback!(handle_ping)) +//! .namespace("mainspace-client") +//! // register callback inline +//! .on("something", callback!(ctx, event, async move { +//! println!("I think the server did something"); +//! ctx.emitter.emit_response_to(event.id(), "mainspace-server", "ok", ()).await?; +//! Ok(()) +//! })) +//! .build() +//! .build_client().await.unwrap(); +//! +//! // emit an initial event +//! let response = ctx.emitter.emit("ping", ()).await.unwrap().await_reply(&ctx).await.unwrap(); +//! assert_eq!(response.name(), "pong"); +//! } //! ``` //! //! Server Example: //! ```no_run //! use typemap_rev::TypeMapKey; //! use rmp_ipc::IPCBuilder; +//! use rmp_ipc::callback; //! //! struct MyKey; //! @@ -45,13 +52,13 @@ //! IPCBuilder::new() //! .address("127.0.0.1:2020") //! // register callback -//! .on("ping", |ctx, event| Box::pin(async move { +//! .on("ping", callback!(ctx, event, async move { //! println!("Received ping event."); //! ctx.emitter.emit_response(event.id(), "pong", ()).await?; //! Ok(()) //! })) //! .namespace("mainspace-server") -//! .on("do-something", |ctx, event| Box::pin(async move { +//! .on("do-something", callback!(ctx, event, async move { //! println!("Doing something"); //! { //! // access data @@ -75,11 +82,13 @@ mod tests; pub mod error; mod events; mod ipc; +mod macros; mod namespaces; pub use events::error_event; pub use events::event::Event; pub use ipc::builder::IPCBuilder; pub use ipc::*; +pub use macros::*; pub use namespaces::builder::NamespaceBuilder; pub use namespaces::namespace::Namespace; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 00000000..90682256 --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,9 @@ +#[macro_export] +macro_rules! callback { + ($cb:ident) => { + |ctx, event| Box::pin($cb(ctx, event)) + }; + ($ctx:ident, $event:ident,$cb:expr) => { + move |$ctx, $event| Box::pin($cb) + }; +} diff --git a/src/tests/ipc_tests.rs b/src/tests/ipc_tests.rs index 22b67fc7..4595df31 100644 --- a/src/tests/ipc_tests.rs +++ b/src/tests/ipc_tests.rs @@ -1,4 +1,5 @@ use self::super::utils::PingEventData; +use crate::callback; use crate::context::Context; use crate::error::Error; use crate::error::Result; @@ -64,7 +65,7 @@ async fn it_receives_events() { fn get_builder_with_ping_mainspace(address: &str) -> IPCBuilder { IPCBuilder::new() .namespace("mainspace") - .on("ping", |ctx, e| Box::pin(handle_ping_event(ctx, e))) + .on("ping", callback!(handle_ping_event)) .build() .address(address) } @@ -115,21 +116,20 @@ fn get_builder_with_error_handling(error_occurred: Arc, address: &st .on("ping", move |_, _| { Box::pin(async move { Err(Error::from("ERRROROROROR")) }) }) - .on("error", { - move |ctx, e| { - Box::pin(async move { - let error = e.data::()?; - assert!(error.message.len() > 0); - assert_eq!(error.code, 500); - { - let data = ctx.data.read().await; - let error_occurred = data.get::().unwrap(); - error_occurred.store(true, Ordering::SeqCst); - } - Ok(()) - }) - } - }) + .on( + "error", + callback!(ctx, event, async move { + let error = event.data::()?; + assert!(error.message.len() > 0); + assert_eq!(error.code, 500); + { + let data = ctx.data.read().await; + let error_occurred = data.get::().unwrap(); + error_occurred.store(true, Ordering::SeqCst); + } + Ok(()) + }), + ) .address(address) }