zero-trust-rps 0.0.5

Online Multiplayer Rock Paper Scissors
Documentation
use std::{fmt::Debug, future::Future};

use tokio::sync::mpsc;
use tokio::sync::mpsc::{Sender, UnboundedSender};

#[derive(thiserror::Error, Debug)]
pub enum SendError {
    #[error("Channel closed")]
    ChannelClosed,
}

impl<T: Debug> From<mpsc::error::SendError<T>> for SendError {
    fn from(value: mpsc::error::SendError<T>) -> Self {
        log::debug!("Tried to send {:?}, but {value}", value.0);
        SendError::ChannelClosed
    }
}

pub trait AsyncChannelSender<T: Send>: Send {
    fn send(&self, value: T) -> impl Future<Output = Result<(), SendError>> + Send;
}

impl<TFrom: Send, TTo: From<TFrom> + Debug + Send> AsyncChannelSender<TFrom>
    for UnboundedSender<TTo>
{
    async fn send(&self, value: TFrom) -> Result<(), SendError> {
        Ok(UnboundedSender::<TTo>::send(self, value.into())?)
    }
}

impl<TFrom: Send, TTo: From<TFrom> + Debug + Send> AsyncChannelSender<TFrom> for Sender<TTo> {
    async fn send(&self, value: TFrom) -> Result<(), SendError> {
        Ok(Sender::<TTo>::send(self, value.into()).await?)
    }
}

impl<T: Send> AsyncChannelSender<T> for () {
    async fn send(&self, _: T) -> Result<(), SendError> {
        Ok(())
    }
}