diff --git a/CHANGELOG.md b/CHANGELOG.md index 1643cec7..d291403d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - The build.rs example in example_package now correctly informs cargo of filesystem dependencies +- The `advertise_serveice` method in `rosbridge/client.rs` now accepts closures ### Fixed diff --git a/roslibrust/examples/service_server.rs b/roslibrust/examples/service_server.rs index 44eb90c1..aa4b5bae 100644 --- a/roslibrust/examples/service_server.rs +++ b/roslibrust/examples/service_server.rs @@ -7,8 +7,11 @@ roslibrust_codegen_macro::find_and_generate_ros_messages!("assets/ros1_common_in // a canned response. fn my_service( request: std_srvs::SetBoolRequest, + my_string: &str, ) -> Result> { log::info!("Got request to set bool: {request:?}"); + log::info!("Using my string: {}", my_string); // Use the string here + Ok(std_srvs::SetBoolResponse { success: true, message: "You set my bool!".to_string(), @@ -48,10 +51,19 @@ async fn main() -> Result<(), Box> { // Create a new client let client = ClientHandle::new("ws://localhost:9090").await?; + // The string you want to pass in to the closure + let my_string = "Some string"; + // Actually advertise our service // The handle returned here establishes the lifetime of our service and dropping it will unadvertise the service let _handle = client - .advertise_service::("/my_set_bool", my_service) + .advertise_service::( + "/my_set_bool", + move |request: std_srvs::SetBoolRequest| -> Result< + std_srvs::SetBoolResponse, + Box, + > { my_service(request, my_string) }, + ) .await?; // Now try manually calling the service with the command line! diff --git a/roslibrust/src/rosbridge/client.rs b/roslibrust/src/rosbridge/client.rs index d391d331..4e3d83c0 100644 --- a/roslibrust/src/rosbridge/client.rs +++ b/roslibrust/src/rosbridge/client.rs @@ -420,14 +420,21 @@ impl ClientHandle { /// Service will be active until the handle is dropped! /// /// See examples/service_server.rs for usage. - pub async fn advertise_service( + pub async fn advertise_service( &self, topic: &str, - server: fn( - T::Request, - ) - -> Result>, - ) -> RosLibRustResult { + server: F, + ) -> RosLibRustResult + where + T: RosServiceType, + F: Fn( + T::Request, + ) + -> Result> + + Send + + Sync + + 'static, + { self.check_for_disconnect()?; { let client = self.inner.read().await; diff --git a/roslibrust/src/rosbridge/integration_tests.rs b/roslibrust/src/rosbridge/integration_tests.rs index fd11c38b..047f52ac 100644 --- a/roslibrust/src/rosbridge/integration_tests.rs +++ b/roslibrust/src/rosbridge/integration_tests.rs @@ -249,7 +249,7 @@ mod integration_tests { let topic = "/self_service_call"; let handle = client - .advertise_service::(topic, cb) + .advertise_service::(topic, cb) .await .expect("Failed to advertise service");