use std::task::{Context, Poll};
use crate::tokio::sync::mpmc;
pub struct Receiver<T> {
inner: mpmc::Receiver<T>,
}
pub struct Sender<T> {
inner: mpmc::Sender<T>,
}
impl<T> std::fmt::Debug for Receiver<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Receiver").finish_non_exhaustive()
}
}
impl<T> std::fmt::Debug for Sender<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sender").finish_non_exhaustive()
}
}
impl<T> Receiver<T> {
pub fn recv(&mut self) -> Result<T, mpmc::RecvError> {
self.inner.recv()
}
pub fn try_recv(&mut self) -> Result<T, mpmc::TryRecvError> {
self.inner.try_recv()
}
pub fn recv_timeout(
&mut self,
timeout: std::time::Duration,
) -> Result<T, mpmc::RecvTimeoutError> {
self.inner.recv_timeout(timeout)
}
pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<T>> {
self.inner.poll_recv(cx)
}
pub async fn recv_async(&mut self) -> Result<T, mpmc::RecvError> {
self.inner.recv_async().await
}
}
#[derive(thiserror::Error)]
pub enum SendError<T> {
#[error("Disconnected")]
Disconnected(T),
}
impl<T> std::fmt::Debug for SendError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Disconnected(_t) => f
.debug_tuple("SendError::Disconnected")
.finish_non_exhaustive(),
}
}
}
impl<T> From<mpmc::SendError<T>> for SendError<T> {
fn from(e: mpmc::SendError<T>) -> Self {
Self::Disconnected(e.0)
}
}
#[derive(thiserror::Error)]
pub enum TrySendError<T> {
#[error("Full")]
Full(T),
#[error("Disconnected")]
Disconnected(T),
}
impl<T> std::fmt::Debug for TrySendError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Full(_t) => f.debug_tuple("TrySendError::Full").finish_non_exhaustive(),
Self::Disconnected(_t) => f
.debug_tuple("TrySendError::Disconnected")
.finish_non_exhaustive(),
}
}
}
impl<T> From<mpmc::TrySendError<T>> for TrySendError<T> {
fn from(err: mpmc::TrySendError<T>) -> Self {
match err {
mpmc::TrySendError::Full(t) => Self::Full(t),
mpmc::TrySendError::Disconnected(t) => Self::Disconnected(t),
}
}
}
impl<T> From<SendError<T>> for TrySendError<T> {
fn from(e: SendError<T>) -> Self {
match e {
SendError::Disconnected(t) => Self::Disconnected(t),
}
}
}
impl<T> From<mpmc::SendError<T>> for TrySendError<T> {
fn from(e: mpmc::SendError<T>) -> Self {
match e {
mpmc::SendError(t) => Self::Disconnected(t),
}
}
}
impl<T> Sender<T> {
pub fn send(&self, value: T) -> Result<(), SendError<T>> {
Ok(self.inner.send(value)?)
}
#[allow(clippy::unused_async)]
pub async fn send_async(&self, value: T) -> Result<(), SendError<T>> {
Ok(self.inner.send(value)?)
}
pub fn try_send(&self, value: T) -> Result<(), TrySendError<T>> {
Ok(self.inner.send(value)?)
}
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
#[must_use]
pub fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
let (tx, rx) = mpmc::unbounded();
(Sender { inner: tx }, Receiver { inner: rx })
}