use rosidl_runtime_rs::Message;
use super::{MessageInfo, SubscriptionHandle};
use crate::{RclrsError, RclrsErrorFilter, ReadOnlyLoanedMessage, WorkerCommands};
use futures::future::BoxFuture;
use std::sync::Arc;
pub enum NodeSubscriptionCallback<T: Message> {
Regular(Box<dyn FnMut(T) -> BoxFuture<'static, ()> + Send>),
RegularWithMessageInfo(Box<dyn FnMut(T, MessageInfo) -> BoxFuture<'static, ()> + Send>),
Boxed(Box<dyn FnMut(Box<T>) -> BoxFuture<'static, ()> + Send>),
BoxedWithMessageInfo(Box<dyn FnMut(Box<T>, MessageInfo) -> BoxFuture<'static, ()> + Send>),
#[allow(clippy::type_complexity)]
Loaned(Box<dyn FnMut(ReadOnlyLoanedMessage<T>) -> BoxFuture<'static, ()> + Send>),
#[allow(clippy::type_complexity)]
LoanedWithMessageInfo(
Box<dyn FnMut(ReadOnlyLoanedMessage<T>, MessageInfo) -> BoxFuture<'static, ()> + Send>,
),
}
impl<T: Message> NodeSubscriptionCallback<T> {
pub(super) fn execute(
&mut self,
handle: &Arc<SubscriptionHandle>,
commands: &WorkerCommands,
) -> Result<(), RclrsError> {
let mut evaluate = || {
match self {
NodeSubscriptionCallback::Regular(cb) => {
let (msg, _) = handle.take::<T>()?;
commands.run_async(cb(msg));
}
NodeSubscriptionCallback::RegularWithMessageInfo(cb) => {
let (msg, msg_info) = handle.take::<T>()?;
commands.run_async(cb(msg, msg_info));
}
NodeSubscriptionCallback::Boxed(cb) => {
let (msg, _) = handle.take_boxed::<T>()?;
commands.run_async(cb(msg));
}
NodeSubscriptionCallback::BoxedWithMessageInfo(cb) => {
let (msg, msg_info) = handle.take_boxed::<T>()?;
commands.run_async(cb(msg, msg_info));
}
NodeSubscriptionCallback::Loaned(cb) => {
let (msg, _) = handle.take_loaned::<T>()?;
commands.run_async(cb(msg));
}
NodeSubscriptionCallback::LoanedWithMessageInfo(cb) => {
let (msg, msg_info) = handle.take_loaned::<T>()?;
commands.run_async(cb(msg, msg_info));
}
}
Ok(())
};
evaluate().take_failed_ok()
}
}