#[cfg(async_channel_impl = "tokio")]
mod inner {
pub use tokio::sync::oneshot::{error::TryRecvError as OneShotTryRecvError, Receiver, Sender};
#[derive(Debug, PartialEq, Eq)]
pub struct OneShotRecvError;
impl From<tokio::sync::oneshot::error::RecvError> for OneShotRecvError {
fn from(_: tokio::sync::oneshot::error::RecvError) -> Self {
Self
}
}
impl std::fmt::Display for OneShotRecvError {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(fmt, stringify!(OneShotRecvError))
}
}
impl std::error::Error for OneShotRecvError {}
pub struct OneShotSender<T>(pub(super) Sender<T>);
pub struct OneShotReceiver<T>(pub(super) Receiver<T>);
#[must_use]
pub fn oneshot<T>() -> (OneShotSender<T>, OneShotReceiver<T>) {
let (sender, receiver) = tokio::sync::oneshot::channel();
(OneShotSender(sender), OneShotReceiver(receiver))
}
}
#[cfg(async_channel_impl = "flume")]
mod inner {
use flume::{Receiver, Sender};
pub use flume::{RecvError as OneShotRecvError, TryRecvError as OneShotTryRecvError};
pub struct OneShotSender<T>(pub(super) Sender<T>);
pub struct OneShotReceiver<T>(pub(super) Receiver<T>);
#[must_use]
pub fn oneshot<T>() -> (OneShotSender<T>, OneShotReceiver<T>) {
let (sender, receiver) = flume::bounded(1);
(OneShotSender(sender), OneShotReceiver(receiver))
}
}
#[cfg(not(any(async_channel_impl = "flume", async_channel_impl = "tokio")))]
mod inner {
use async_std::channel::{Receiver, Sender};
pub use async_std::channel::{
RecvError as OneShotRecvError, TryRecvError as OneShotTryRecvError,
};
pub struct OneShotSender<T>(pub(super) Sender<T>);
pub struct OneShotReceiver<T>(pub(super) Receiver<T>);
#[must_use]
pub fn oneshot<T>() -> (OneShotSender<T>, OneShotReceiver<T>) {
let (sender, receiver) = async_std::channel::bounded(1);
(OneShotSender(sender), OneShotReceiver(receiver))
}
}
pub use inner::*;
impl<T> OneShotSender<T> {
pub fn send(self, msg: T) {
#[cfg(not(any(async_channel_impl = "flume", async_channel_impl = "tokio")))]
if self.0.try_send(msg).is_err() {
tracing::warn!("Could not send msg on OneShotSender, did the receiver drop?");
}
#[cfg(any(async_channel_impl = "flume", async_channel_impl = "tokio"))]
if self.0.send(msg).is_err() {
tracing::warn!("Could not send msg on OneShotSender, did the receiver drop?");
}
}
}
impl<T> OneShotReceiver<T> {
pub async fn recv(self) -> Result<T, OneShotRecvError> {
#[cfg(async_channel_impl = "tokio")]
let result = self.0.await.map_err(Into::into);
#[cfg(async_channel_impl = "flume")]
let result = self.0.recv_async().await;
#[cfg(not(any(async_channel_impl = "flume", async_channel_impl = "tokio")))]
let result = self.0.recv().await;
result
}
}
impl<T> std::fmt::Debug for OneShotSender<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OneShotSender").finish()
}
}
impl<T> std::fmt::Debug for OneShotReceiver<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OneShotReceiver").finish()
}
}