use std::{fmt, io::ErrorKind};
use nix::errno::Errno;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimerErrorType
{
Expired,
TimerError(Errno),
QueueEmpty,
EPoll(Errno),
EventFd(Errno),
EPollAlreadyPolling,
Conversion,
ExternalError,
Duplicate,
AlreadyPolled,
NotFound,
TicketInstanceGone,
BelongOtherInstance,
ChannelDisconnected,
Poisoned,
SpawnError(ErrorKind),
ReferenceGone,
MpscTimeout,
ZeroRelativeTime,
}
impl fmt::Display for TimerErrorType
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self
{
Self::Expired =>
write!(f, "absolute time has expired"),
Self::TimerError(e) =>
write!(f, "timer setup error: {}", e.desc()),
Self::QueueEmpty =>
write!(f, "the queue is empty"),
Self::EPoll(errno) =>
write!(f, "epoll() error: {}", errno.desc()),
Self::EventFd(errno) =>
write!(f, "eventfd() error: {}", errno.desc()),
Self::EPollAlreadyPolling =>
write!(f, "other thread already polling"),
Self::Conversion =>
write!(f, "cannot convert time"),
Self::ExternalError =>
write!(f, "external error"),
Self::Duplicate =>
write!(f, "duplicate"),
Self::AlreadyPolled =>
write!(f, "instance is already on watch"),
Self::NotFound =>
write!(f, "not found"),
Self::TicketInstanceGone =>
write!(f, "ticket dropped"),
Self::BelongOtherInstance =>
write!(f, "item belongs to other instance"),
Self::ChannelDisconnected =>
write!(f, "MPSC sender has disconnected from receiver"),
Self::Poisoned =>
write!(f, "mutex poisoned"),
Self::SpawnError(e) =>
write!(f, "thread spawn error: {}", e),
Self::ReferenceGone =>
write!(f, "Weak reference gone"),
Self::MpscTimeout =>
write!(f, "MPSC timeout"),
Self::ZeroRelativeTime =>
write!(f, "The relative time for offset is zero.")
}
}
}
#[derive(Debug, Clone)]
pub struct TimerError
{
reason: TimerErrorType,
msg: String
}
impl Eq for TimerError {}
impl PartialEq for TimerError
{
fn eq(&self, other: &Self) -> bool
{
return self.reason == other.reason;
}
}
impl fmt::Display for TimerError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{} {}", self.reason, self.msg)
}
}
impl TimerError
{
pub
fn new(reason: TimerErrorType, msg: String) -> Self
{
return Self{ reason, msg };
}
pub
fn get_error_type(&self) -> TimerErrorType
{
return self.reason;
}
pub
fn get_error_msg(&self) -> &str
{
return &self.msg;
}
}
pub type TimerResult<R> = Result<R, TimerError>;
#[macro_export]
macro_rules! timer_err
{
($reason:expr,$($arg:tt)*) => (
return std::result::Result::Err( $crate::error::TimerError::new($reason, format!($($arg)*)) )
)
}
#[macro_export]
macro_rules! map_timer_err
{
($reason:expr, $($arg:tt)*) => (
$crate::error::TimerError::new($reason, format!($($arg)*))
)
}