use serde::{Deserialize, Serialize};
use std::{error::Error, fmt};
use super::super::{ClosedReason, SendErrorExt, Sending, mpsc};
use crate::{RemoteSend, codec};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum SendError<T> {
Closed(T),
Failed,
}
impl<T> SendError<T> {
pub fn is_closed(&self) -> bool {
matches!(self, Self::Closed(_))
}
#[deprecated = "a remoc::rch::oneshot::SendError is always due to disconnection"]
pub fn is_disconnected(&self) -> bool {
true
}
#[deprecated = "a remoc::rch::oneshot::SendError is always final"]
pub fn is_final(&self) -> bool {
true
}
pub fn without_item(self) -> SendError<()> {
match self {
Self::Closed(_) => SendError::Closed(()),
Self::Failed => SendError::Failed,
}
}
}
impl<T> SendErrorExt for SendError<T> {
fn is_closed(&self) -> bool {
self.is_closed()
}
fn is_disconnected(&self) -> bool {
#[allow(deprecated)]
self.is_disconnected()
}
fn is_final(&self) -> bool {
#[allow(deprecated)]
self.is_final()
}
fn is_item_specific(&self) -> bool {
false
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Closed(_) => write!(f, "channel is closed"),
Self::Failed => write!(f, "send error"),
}
}
}
impl<T> From<mpsc::TrySendError<T>> for SendError<T> {
fn from(err: mpsc::TrySendError<T>) -> Self {
match err {
mpsc::TrySendError::Closed(err) => Self::Closed(err),
_ => Self::Failed,
}
}
}
impl<T> Error for SendError<T> where T: fmt::Debug {}
#[derive(Serialize, Deserialize)]
#[serde(bound(serialize = "T: RemoteSend, Codec: codec::Codec"))]
#[serde(bound(deserialize = "T: RemoteSend, Codec: codec::Codec"))]
pub struct Sender<T, Codec = codec::Default>(pub(crate) mpsc::Sender<T, Codec, 1>);
impl<T, Codec> fmt::Debug for Sender<T, Codec> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Sender").finish()
}
}
impl<T, Codec> Sender<T, Codec>
where
T: RemoteSend,
Codec: codec::Codec,
{
pub fn send(self, value: T) -> Result<Sending<T>, SendError<T>> {
self.0.try_send(value).map_err(|err| err.into())
}
pub async fn closed(&self) {
self.0.closed().await
}
pub fn closed_reason(&self) -> Option<ClosedReason> {
self.0.closed_reason()
}
pub fn is_closed(&self) -> bool {
self.0.is_closed()
}
pub fn max_item_size(&self) -> usize {
self.0.max_item_size()
}
pub fn set_max_item_size(&mut self, max_item_size: usize) {
self.0.set_max_item_size(max_item_size)
}
}