use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use tracing::error;
use tokio::sync::oneshot;
pub struct Reply<T> {
inner: oneshot::Receiver<T>,
}
impl<T> Future for Reply<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match Future::poll(Pin::new(&mut self.get_mut().inner), cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(Ok(value)) => Poll::Ready(value),
Poll::Ready(Err(_)) => {
error!(
"A reply from the async channel has stalled out because \
its sender dropped. Please report this as a bug."
);
Poll::Pending
}
}
}
}
impl<T> Reply<T> {
pub fn try_recv(&mut self) -> Option<T> {
self.inner.try_recv().ok()
}
pub fn safely(self) -> oneshot::Receiver<T> {
self.inner
}
pub fn is_terminated(&self) -> bool {
self.inner.is_terminated()
}
pub fn is_available(&self) -> bool {
!self.inner.is_empty()
}
pub fn is_pending(&self) -> bool {
self.inner.is_empty() && !self.is_terminated()
}
pub(crate) fn new(receiver: oneshot::Receiver<T>) -> Self {
Self { inner: receiver }
}
}