use std::io;
#[cfg(feature = "rpc")]
use n0_error::e;
use n0_error::stack_error;
#[cfg(feature = "rpc")]
use crate::rpc::{ConnectionClose, ErrorCode, RpcSendError};
pub mod mpsc;
pub mod none;
pub mod oneshot;
#[stack_error(derive, add_meta, from_sources)]
#[non_exhaustive]
pub enum SendError {
#[error("Receiver closed")]
ReceiverClosed,
#[cfg(feature = "rpc")]
#[error("Remote channel failed")]
Rpc { source: RpcSendError },
}
impl From<SendError> for io::Error {
fn from(e: SendError) -> Self {
match e {
SendError::ReceiverClosed { .. } => io::Error::new(io::ErrorKind::BrokenPipe, e),
#[cfg(feature = "rpc")]
SendError::Rpc { source, .. } => source.into(),
}
}
}
#[cfg(feature = "rpc")]
impl SendError {
pub fn remote_code(&self) -> Option<ErrorCode> {
match self {
Self::Rpc { source, .. } => source.remote_code(),
_ => None,
}
}
}
#[cfg(feature = "rpc")]
impl From<noq::WriteError> for SendError {
fn from(err: noq::WriteError) -> Self {
match err {
noq::WriteError::Stopped(code) => match ErrorCode::from_code(code) {
Some(code) => e!(RpcSendError::Remote { code }).into(),
None => e!(SendError::ReceiverClosed),
},
noq::WriteError::ConnectionLost(ref cause) => {
match ConnectionClose::from_error(cause) {
Some(close) => e!(RpcSendError::ConnectionClosed { close }).into(),
None => e!(RpcSendError::ConnectionFailed, err.into()).into(),
}
}
err => e!(RpcSendError::ConnectionFailed, err.into()).into(),
}
}
}