timer_deque_rs/
error.rs

1/*-
2 * timer-deque-rs - a Rust crate which provides timer and timer queues based on target OS
3 *  functionality.
4 * 
5 * Copyright (C) 2025 Aleksandr Morozov alex@nixd.org
6 *  4neko.org alex@4neko.org
7 * 
8 * The timer-rs crate can be redistributed and/or modified
9 * under the terms of either of the following licenses:
10 *
11 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
12 *                     
13 *   2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
14 */
15
16use std::{fmt, io::ErrorKind};
17
18use nix::errno::Errno;
19
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum TimerErrorType
23{
24    /// The procvided time has expired before setting
25    Expired,
26
27    /// Error in timer subsystem
28    TimerError(Errno),
29
30    /// Performing oprtation on empty queue.
31    QueueEmpty,
32
33    /// Epoll returned error [Errno].
34    EPoll(Errno),
35
36    EventFd(Errno),
37
38    /// Already polling
39    EPollAlreadyPolling,
40
41    /// Can not convert time.
42    Conversion,
43
44    /// Some error which came from other crate.
45    ExternalError,
46
47    /// Duplicate record.
48    Duplicate,
49
50    /// Already polled
51    AlreadyPolled,
52
53    /// Item not found
54    NotFound,
55
56    /// Item belong to other instance
57    BelongOtherInstance,
58
59    /// MPSC channel disconnected.
60    ChannelDisconnected,
61
62    /// Thread poisoned
63    Poisoned,
64
65    SpawnError(ErrorKind),
66
67    ReferenceGone,
68
69    MpscTimeout,
70}
71
72impl fmt::Display for TimerErrorType
73{
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
75    {
76        match self
77        {
78            Self::Expired => 
79                write!(f, "absolute time has expired"),
80            Self::TimerError(e) => 
81                write!(f, "timer setup error: {}", e.desc()),
82            Self::QueueEmpty => 
83                write!(f, "the queue is empty"),
84            Self::EPoll(errno) => 
85                write!(f, "epoll() error: {}", errno.desc()),
86            Self::EventFd(errno) => 
87                write!(f, "eventfd() error: {}", errno.desc()),
88            Self::EPollAlreadyPolling =>
89                write!(f, "other thread already polling"),
90            Self::Conversion => 
91                write!(f, "cannot convert time"),
92            Self::ExternalError => 
93                write!(f, "external error"),
94            Self::Duplicate => 
95                write!(f, "duplicate"),
96            Self::AlreadyPolled =>
97                write!(f, "instance is already on watch"),
98            Self::NotFound => 
99                write!(f, "not found"),
100            Self::BelongOtherInstance =>
101                write!(f, "item belongs to other instance"),
102            Self::ChannelDisconnected => 
103                write!(f, "MPSC sender has disconnected from receiver"),
104            Self::Poisoned =>
105                write!(f, "mutex poisoned"),
106            Self::SpawnError(e) =>
107                write!(f, "thread spawn error: {}", e),
108            Self::ReferenceGone =>
109                write!(f, "Weak reference gone"),
110            Self::MpscTimeout => 
111                write!(f, "MPSC timeout"),
112        }
113    }
114}
115
116/// Error storage.
117#[derive(Debug, Clone)]
118pub struct TimerError
119{
120    /// Error code.
121    reason: TimerErrorType,
122
123    /// Error descrition.
124    msg: String
125}
126
127impl Eq for TimerError {}
128
129impl PartialEq for TimerError
130{
131    fn eq(&self, other: &Self) -> bool 
132    {
133        return self.reason == other.reason;
134    }
135}
136
137impl fmt::Display for TimerError
138{
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
140    {
141        write!(f, "{} {}", self.reason, self.msg)
142    }
143}
144
145impl TimerError
146{
147    pub 
148    fn new(reason: TimerErrorType, msg: String) -> Self
149    {
150        return Self{ reason, msg };
151    }
152
153    pub 
154    fn get_error_type(&self) -> TimerErrorType
155    {
156        return self.reason;
157    }
158}
159
160/// Alias for the [Result] used by timer queues.
161pub type TimerResult<R> = Result<R, TimerError>;
162
163#[macro_export]
164macro_rules! timer_err
165{
166    ($reason:expr,$($arg:tt)*) => (
167        return std::result::Result::Err( $crate::error::TimerError::new($reason, format!($($arg)*)) )
168    )
169}
170
171#[macro_export]
172macro_rules! map_timer_err
173{
174    ($reason:expr, $($arg:tt)*) => (
175        $crate::error::TimerError::new($reason, format!($($arg)*))
176    )
177}