Make ignoring server reply easier

This commit is contained in:
Joscha 2022-08-18 17:18:37 +02:00
parent 4dcf09a136
commit f12b28b121

View file

@ -5,6 +5,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::Infallible; use std::convert::Infallible;
use std::error; use std::error;
use std::future::Future;
use std::time::Duration; use std::time::Duration;
use futures::channel::oneshot; use futures::channel::oneshot;
@ -388,15 +389,13 @@ pub struct ConnTx {
} }
impl ConnTx { impl ConnTx {
pub async fn send<C>(&self, cmd: C) -> Result<C::Reply, Error> async fn finish_send<C>(
rx: oneshot::Receiver<PendingReply<Result<Data, String>>>,
) -> Result<C::Reply, Error>
where where
C: Command + Into<Data>, C: Command,
C::Reply: TryFrom<Data>, C::Reply: TryFrom<Data>,
{ {
let (tx, rx) = oneshot::channel();
self.event_tx
.send(Event::SendCmd(cmd.into(), tx))
.map_err(|_| Error::ConnectionClosed)?;
let pending_reply = rx let pending_reply = rx
.await .await
// This should only happen if something goes wrong during encoding // This should only happen if something goes wrong during encoding
@ -414,6 +413,27 @@ impl ConnTx {
data.try_into().map_err(|_| Error::IncorrectReplyType) data.try_into().map_err(|_| Error::IncorrectReplyType)
} }
/// Send a command to the server.
///
/// Returns a future containing the server's reply. This future does not
/// have to be awaited and can be safely ignored if you are not interested
/// in the reply.
///
/// This function may return before the command was sent. To ensure that it
/// was sent, await the returned future first.
///
/// When called multiple times, this function guarantees that the commands
/// are sent in the order that the function is called.
pub fn send<C>(&self, cmd: C) -> impl Future<Output = Result<C::Reply, Error>>
where
C: Command + Into<Data>,
C::Reply: TryFrom<Data>,
{
let (tx, rx) = oneshot::channel();
let _ = self.event_tx.send(Event::SendCmd(cmd.into(), tx));
Self::finish_send::<C>(rx)
}
pub async fn status(&self) -> Result<Status, Error> { pub async fn status(&self) -> Result<Status, Error> {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
self.event_tx self.event_tx