use ntex_util::future::Either;
use crate::codec::{AmqpCodecError, AmqpFrame, ProtocolIdError, SaslFrame, protocol};
use crate::error::{AmqpDispatcherError, AmqpProtocolError};
#[derive(Debug, thiserror::Error)]
pub enum ServerError<E> {
#[error("Message handler service error")]
Service(E),
#[error("Handshake error: {}", 0)]
Handshake(HandshakeError),
#[error("Amqp codec error: {:?}", 0)]
Codec(AmqpCodecError),
#[error("Amqp protocol error: {:?}", 0)]
Protocol(AmqpProtocolError),
#[error("Amqp dispatcher error: {:?}", 0)]
Dispatcher(AmqpDispatcherError),
#[error("Control service init error")]
ControlServiceError,
#[error("Publish service init error")]
PublishServiceError,
}
impl<E> From<AmqpCodecError> for ServerError<E> {
fn from(err: AmqpCodecError) -> Self {
ServerError::Codec(err)
}
}
impl<E> From<AmqpProtocolError> for ServerError<E> {
fn from(err: AmqpProtocolError) -> Self {
ServerError::Protocol(err)
}
}
impl<E> From<HandshakeError> for ServerError<E> {
fn from(err: HandshakeError) -> Self {
ServerError::Handshake(err)
}
}
#[derive(Debug, From, thiserror::Error)]
pub enum HandshakeError {
#[error("Amqp codec error: {:?}", 0)]
Codec(AmqpCodecError),
#[error("Handshake timeout")]
Timeout,
#[error("Peer disconnected")]
ProtocolNegotiation(ProtocolIdError),
#[from(ignore)]
#[error("Expect open frame, got: {:?}", 0)]
ExpectOpenFrame(AmqpFrame),
#[error("Unexpected frame, got: {:?}", 0)]
Unexpected(protocol::Frame),
#[error("Unexpected sasl frame: {:?}", 0)]
UnexpectedSaslFrame(Box<SaslFrame>),
#[error("Unexpected sasl frame body: {:?}", 0)]
UnexpectedSaslBodyFrame(Box<protocol::SaslFrameBody>),
#[error("Unsupported sasl mechanism: {}", 0)]
UnsupportedSaslMechanism(String),
#[error("Sasl error code: {:?}", 0)]
Sasl(protocol::SaslCode),
#[error("Peer disconnected, with error {:?}", 0)]
Disconnected(Option<std::io::Error>),
}
impl From<Either<AmqpCodecError, std::io::Error>> for HandshakeError {
fn from(err: Either<AmqpCodecError, std::io::Error>) -> Self {
match err {
Either::Left(err) => HandshakeError::Codec(err),
Either::Right(err) => HandshakeError::Disconnected(Some(err)),
}
}
}
impl From<Either<ProtocolIdError, std::io::Error>> for HandshakeError {
fn from(err: Either<ProtocolIdError, std::io::Error>) -> Self {
match err {
Either::Left(err) => HandshakeError::ProtocolNegotiation(err),
Either::Right(err) => HandshakeError::Disconnected(Some(err)),
}
}
}