use crate::transport::{TransportError, wire::CodecError};
use core::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum EndpointOp {
Send,
Recv,
Offer,
}
#[derive(Clone, Copy)]
pub struct EndpointError {
op: EndpointOp,
kind: EndpointErrorKind,
}
impl fmt::Debug for EndpointError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug = formatter.debug_struct("EndpointError");
debug.field("operation", &self.op_name());
debug.field("kind", &self.kind).finish()
}
}
impl EndpointError {
#[inline]
pub(super) fn new<E>(op: EndpointOp, error: E) -> Self
where
EndpointErrorKind: From<E>,
{
Self {
op,
kind: EndpointErrorKind::from(error),
}
}
#[inline]
const fn op_name(&self) -> &'static str {
match self.op {
EndpointOp::Send => "send",
EndpointOp::Recv => "recv",
EndpointOp::Offer => "offer",
}
}
}
#[derive(Clone, Copy)]
pub(super) enum EndpointErrorKind {
Codec(CodecError),
Transport(TransportError),
PhaseInvariant,
LabelMismatch { expected: u8, actual: u8 },
ResolverReject { resolver_id: u16 },
SessionFault(crate::rendezvous::SessionFaultKind),
}
impl fmt::Debug for EndpointErrorKind {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Codec(error) => formatter.debug_tuple("Codec").field(error).finish(),
Self::Transport(error) => formatter.debug_tuple("Transport").field(error).finish(),
Self::PhaseInvariant => formatter.write_str("PhaseInvariant"),
Self::LabelMismatch { expected, actual } => formatter
.debug_struct("LabelMismatch")
.field("expected", expected)
.field("actual", actual)
.finish(),
Self::ResolverReject { resolver_id } => formatter
.debug_struct("ResolverReject")
.field("resolver_id", resolver_id)
.finish(),
Self::SessionFault(kind) => formatter.debug_tuple("SessionFault").field(kind).finish(),
}
}
}
impl From<SendError> for EndpointErrorKind {
#[inline]
fn from(error: SendError) -> Self {
match error {
SendError::Codec(error) => Self::Codec(error),
SendError::Transport(error) => Self::Transport(error),
SendError::PhaseInvariant => Self::PhaseInvariant,
SendError::LabelMismatch { expected, actual } => {
Self::LabelMismatch { expected, actual }
}
SendError::ResolverReject { resolver_id } => Self::ResolverReject { resolver_id },
SendError::SessionFault(kind) => Self::SessionFault(kind),
}
}
}
impl From<RecvError> for EndpointErrorKind {
#[inline]
fn from(error: RecvError) -> Self {
match error {
RecvError::Transport(error) => Self::Transport(error),
RecvError::Codec(error) => Self::Codec(error),
RecvError::PhaseInvariant => Self::PhaseInvariant,
RecvError::LabelMismatch { expected, actual } => {
Self::LabelMismatch { expected, actual }
}
RecvError::ResolverReject { resolver_id } => Self::ResolverReject { resolver_id },
RecvError::SessionFault(kind) => Self::SessionFault(kind),
}
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum SendError {
Codec(CodecError),
Transport(TransportError),
PhaseInvariant,
LabelMismatch { expected: u8, actual: u8 },
ResolverReject { resolver_id: u16 },
SessionFault(crate::rendezvous::SessionFaultKind),
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum RecvError {
Transport(TransportError),
Codec(CodecError),
PhaseInvariant,
LabelMismatch { expected: u8, actual: u8 },
ResolverReject { resolver_id: u16 },
SessionFault(crate::rendezvous::SessionFaultKind),
}
pub(crate) type SendResult<T> = core::result::Result<T, SendError>;
pub(crate) type RecvResult<T> = core::result::Result<T, RecvError>;