use crate::{
ActionServer, ActionServerState, IntoActionServerOptions, Node, RclrsError, RequestedGoal,
TerminatedGoal,
};
use rosidl_runtime_rs::Action;
use std::{
future::Future,
ops::{Deref, DerefMut},
sync::Arc,
};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
pub struct ActionGoalReceiver<A: Action> {
server: ActionServerState<A>,
receiver: UnboundedReceiver<RequestedGoal<A>>,
}
impl<A: Action> Deref for ActionGoalReceiver<A> {
type Target = UnboundedReceiver<RequestedGoal<A>>;
fn deref(&self) -> &Self::Target {
&self.receiver
}
}
impl<A: Action> DerefMut for ActionGoalReceiver<A> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.receiver
}
}
impl<A: Action> ActionGoalReceiver<A> {
#[must_use]
pub fn into_action_server<Task>(
self,
callback: impl FnMut(RequestedGoal<A>) -> Task + Send + Sync + 'static,
) -> ActionServer<A>
where
Task: Future<Output = TerminatedGoal> + Send + Sync + 'static,
{
let Self { server, receiver } = self;
server.drain_receiver_into_callback(receiver, callback);
Arc::new(server)
}
pub(crate) fn new<'a>(
node: &Node,
options: impl IntoActionServerOptions<'a>,
) -> Result<Self, RclrsError> {
let (sender, receiver) = unbounded_channel();
let server = ActionServerState::new_for_receiver(node, options, sender)?;
Ok(Self { server, receiver })
}
pub(super) fn from_server(server: ActionServerState<A>) -> Self {
let (sender, receiver) = unbounded_channel();
server.set_goal_sender(sender);
Self { server, receiver }
}
}