use crate::error::{Error, Result};
use tokio::sync::mpsc::{channel, Receiver, Sender};
pub struct CommandChannelSender<S, R> {
command_sender: Sender<S>,
command_return_receiver: Receiver<R>,
}
impl<S, R> CommandChannelSender<S, R> {
#[allow(clippy::future_not_send)]
pub async fn send_command(&mut self, command: S) -> Result<R> {
match self.command_sender.send(command).await {
Ok(()) => Ok(()),
Err(_e) => Err(Error::ConnectionClosed),
}?;
match self.command_return_receiver.recv().await {
Some(value) => Ok(value),
None => Err(Error::ConnectionClosed),
}
}
}
pub struct CommandChannelReceiver<S, R> {
command_receiver: Receiver<S>,
command_return_sender: Sender<R>,
}
impl<S, R> CommandChannelReceiver<S, R> {
#[allow(clippy::future_not_send)]
pub async fn recv_command(&mut self) -> Result<S> {
let command = match self.command_receiver.recv().await {
Some(value) => Ok(value),
None => Err(Error::ConnectionClosed),
}?;
Ok(command)
}
#[allow(clippy::future_not_send, clippy::needless_pass_by_ref_mut)]
pub async fn command_return(&mut self, command_return: R) -> Result<()> {
match self.command_return_sender.send(command_return).await {
Ok(()) => Ok(()),
Err(_e) => Err(Error::ConnectionClosed),
}
}
}
pub fn command_channel<S, R>() -> (CommandChannelSender<S, R>, CommandChannelReceiver<S, R>) {
let (command_sender, command_receiver) = channel(1);
let (command_return_sender, command_return_receiver) = channel(1);
let sender = CommandChannelSender {
command_sender,
command_return_receiver,
};
let receiver = CommandChannelReceiver {
command_receiver,
command_return_sender,
};
(sender, receiver)
}