use std::{error, fmt, io, num::NonZeroU32};
use crate::message::Message;
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) type SendResult<T> = std::result::Result<T, SendError>;
pub(crate) type SendError = (Message, Error);
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
#[rustfmt::skip]
pub enum Error
{
Interrupted,
OutOfMemory,
InvalidInput,
Busy,
TimedOut,
ConnectionRefused,
Closed,
TryAgain,
NotSupported,
AddressInUse,
IncorrectState,
EntryNotFound,
Protocol,
DestUnreachable,
AddressInvalid,
PermissionDenied,
MessageTooLarge,
ConnectionAborted,
ConnectionReset,
Canceled,
OutOfFiles,
OutOfSpace,
ResourceExists,
ReadOnly,
WriteOnly,
Crypto,
PeerAuth,
NoArgument,
Ambiguous,
BadType,
Internal,
SystemErr(u32),
TransportErr(u32),
#[doc(hidden)]
Unknown(u32),
}
#[cfg_attr(not(feature = "ffi-module"), doc(hidden))]
impl From<NonZeroU32> for Error
{
#[rustfmt::skip]
fn from(code: NonZeroU32) -> Error
{
match code.get() {
nng_sys::NNG_EINTR => Error::Interrupted,
nng_sys::NNG_ENOMEM => Error::OutOfMemory,
nng_sys::NNG_EINVAL => Error::InvalidInput,
nng_sys::NNG_EBUSY => Error::Busy,
nng_sys::NNG_ETIMEDOUT => Error::TimedOut,
nng_sys::NNG_ECONNREFUSED => Error::ConnectionRefused,
nng_sys::NNG_ECLOSED => Error::Closed,
nng_sys::NNG_EAGAIN => Error::TryAgain,
nng_sys::NNG_ENOTSUP => Error::NotSupported,
nng_sys::NNG_EADDRINUSE => Error::AddressInUse,
nng_sys::NNG_ESTATE => Error::IncorrectState,
nng_sys::NNG_ENOENT => Error::EntryNotFound,
nng_sys::NNG_EPROTO => Error::Protocol,
nng_sys::NNG_EUNREACHABLE => Error::DestUnreachable,
nng_sys::NNG_EADDRINVAL => Error::AddressInvalid,
nng_sys::NNG_EPERM => Error::PermissionDenied,
nng_sys::NNG_EMSGSIZE => Error::MessageTooLarge,
nng_sys::NNG_ECONNABORTED => Error::ConnectionAborted,
nng_sys::NNG_ECONNRESET => Error::ConnectionReset,
nng_sys::NNG_ECANCELED => Error::Canceled,
nng_sys::NNG_ENOFILES => Error::OutOfFiles,
nng_sys::NNG_ENOSPC => Error::OutOfSpace,
nng_sys::NNG_EEXIST => Error::ResourceExists,
nng_sys::NNG_EREADONLY => Error::ReadOnly,
nng_sys::NNG_EWRITEONLY => Error::WriteOnly,
nng_sys::NNG_ECRYPTO => Error::Crypto,
nng_sys::NNG_EPEERAUTH => Error::PeerAuth,
nng_sys::NNG_ENOARG => Error::NoArgument,
nng_sys::NNG_EAMBIGUOUS => Error::Ambiguous,
nng_sys::NNG_EBADTYPE => Error::BadType,
nng_sys::NNG_EINTERNAL => Error::Internal,
c if c & nng_sys::NNG_ESYSERR != 0 => Error::SystemErr(c & !nng_sys::NNG_ESYSERR),
c if c & nng_sys::NNG_ETRANERR != 0 => Error::TransportErr(c & !nng_sys::NNG_ETRANERR),
c => Error::Unknown(c),
}
}
}
impl From<SendError> for Error
{
fn from((_, e): SendError) -> Error { e }
}
impl From<Error> for io::Error
{
fn from(e: Error) -> io::Error
{
if let Error::SystemErr(c) = e {
io::Error::from_raw_os_error(c as i32)
}
else {
#[rustfmt::skip]
#[allow(clippy::match_same_arms)]
let new_kind = match e {
Error::Interrupted => io::ErrorKind::Interrupted,
Error::InvalidInput | Error::NoArgument => io::ErrorKind::InvalidInput,
Error::TimedOut => io::ErrorKind::TimedOut,
Error::TryAgain => io::ErrorKind::WouldBlock,
Error::ConnectionRefused => io::ErrorKind::ConnectionRefused,
Error::PermissionDenied => io::ErrorKind::PermissionDenied,
Error::ConnectionAborted => io::ErrorKind::ConnectionAborted,
Error::ConnectionReset => io::ErrorKind::ConnectionReset,
Error::ResourceExists => io::ErrorKind::AlreadyExists,
Error::BadType => io::ErrorKind::InvalidData,
_ => io::ErrorKind::Other,
};
io::Error::new(new_kind, e)
}
}
}
impl error::Error for Error {}
impl fmt::Display for Error
{
#[rustfmt::skip]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
match *self {
Error::Interrupted => write!(f, "Interrupted"),
Error::OutOfMemory => write!(f, "Out of memory"),
Error::InvalidInput => write!(f, "Invalid argument"),
Error::Busy => write!(f, "Resource busy"),
Error::TimedOut => write!(f, "Timed out"),
Error::ConnectionRefused => write!(f, "Connection refused"),
Error::Closed => write!(f, "Object closed"),
Error::TryAgain => write!(f, "Try again"),
Error::NotSupported => write!(f, "Not supported"),
Error::AddressInUse => write!(f, "Address in use"),
Error::IncorrectState => write!(f, "Incorrect state"),
Error::EntryNotFound => write!(f, "Entry not found"),
Error::Protocol => write!(f, "Protocol error"),
Error::DestUnreachable => write!(f, "Destination unreachable"),
Error::AddressInvalid => write!(f, "Address invalid"),
Error::PermissionDenied => write!(f, "Permission denied"),
Error::MessageTooLarge => write!(f, "Message too large"),
Error::ConnectionReset => write!(f, "Connection reset"),
Error::ConnectionAborted => write!(f, "Connection aborted"),
Error::Canceled => write!(f, "Operation canceled"),
Error::OutOfFiles => write!(f, "Out of files"),
Error::OutOfSpace => write!(f, "Out of space"),
Error::ResourceExists => write!(f, "Resource already exists"),
Error::ReadOnly => write!(f, "Read only resource"),
Error::WriteOnly => write!(f, "Write only resource"),
Error::Crypto => write!(f, "Cryptographic error"),
Error::PeerAuth => write!(f, "Peer could not be authenticated"),
Error::NoArgument => write!(f, "Option requires argument"),
Error::Ambiguous => write!(f, "Ambiguous option"),
Error::BadType => write!(f, "Incorrect type"),
Error::Internal => write!(f, "Internal error detected"),
Error::SystemErr(c) => write!(f, "{}", io::Error::from_raw_os_error(c as i32)),
Error::TransportErr(c) => write!(f, "Transport error #{}", c),
Error::Unknown(c) => write!(f, "Unknown error code #{}", c),
}
}
}