rclrs/service/
worker_service_callback.rs1use rosidl_runtime_rs::Service;
2
3use crate::{RclrsError, RclrsErrorFilter, RequestId, ServiceHandle, ServiceInfo};
4
5use std::{any::Any, sync::Arc};
6
7pub enum WorkerServiceCallback<T, Payload>
14where
15 T: Service,
16 Payload: 'static + Send,
17{
18 OnlyRequest(Box<dyn FnMut(&mut Payload, T::Request) -> T::Response + Send>),
20 WithId(Box<dyn FnMut(&mut Payload, T::Request, RequestId) -> T::Response + Send>),
22 WithInfo(Box<dyn FnMut(&mut Payload, T::Request, ServiceInfo) -> T::Response + Send>),
24}
25
26impl<T, Payload> WorkerServiceCallback<T, Payload>
27where
28 T: Service,
29 Payload: 'static + Send,
30{
31 pub(super) fn execute(
32 &mut self,
33 handle: &Arc<ServiceHandle>,
34 any_payload: &mut dyn Any,
35 ) -> Result<(), RclrsError> {
36 let Some(payload) = any_payload.downcast_mut::<Payload>() else {
37 return Err(RclrsError::InvalidPayload {
38 expected: std::any::TypeId::of::<Payload>(),
39 received: (*any_payload).type_id(),
40 });
41 };
42
43 let mut evaluate = || {
44 match self {
45 WorkerServiceCallback::OnlyRequest(cb) => {
46 let (msg, mut rmw_request_id) = handle.take_request::<T>()?;
47 let response = cb(payload, msg);
48 handle.send_response::<T>(&mut rmw_request_id, response)?;
49 }
50 WorkerServiceCallback::WithId(cb) => {
51 let (msg, mut rmw_request_id) = handle.take_request::<T>()?;
52 let request_id = RequestId::from_rmw_request_id(&rmw_request_id);
53 let response = cb(payload, msg, request_id);
54 handle.send_response::<T>(&mut rmw_request_id, response)?;
55 }
56 WorkerServiceCallback::WithInfo(cb) => {
57 let (msg, rmw_service_info) = handle.take_request_with_info::<T>()?;
58 let mut rmw_request_id = rmw_service_info.rmw_request_id();
59 let service_info = ServiceInfo::from_rmw_service_info(&rmw_service_info);
60 let response = cb(payload, msg, service_info);
61 handle.send_response::<T>(&mut rmw_request_id, response)?;
62 }
63 }
64
65 Ok(())
66 };
67
68 evaluate().take_failed_ok()
69 }
70}