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. The MIT License (MIT)
14 *                     
15 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
16 */
17
18use std::{fmt, io::ErrorKind};
19
20#[cfg(target_family = "unix")]
21use nix::errno::Errno;
22
23#[cfg(target_family = "windows")]
24use windows::core::Error;
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub enum TimerErrorType
28{
29    /// The procvided time has expired before setting
30    Expired,
31
32    /// Error in timer subsystem
33    #[cfg(target_family = "unix")]
34    TimerError(Errno),
35
36    #[cfg(target_family = "windows")]
37    TimerError(Error),
38
39    /// Performing oprtation on empty queue.
40    QueueEmpty,
41
42    /// Epoll returned error [Errno].
43    #[cfg(target_family = "unix")]
44    EPoll(Errno),
45
46    #[cfg(target_family = "windows")]
47    EPoll(Error),
48
49    #[cfg(target_family = "unix")]
50    EventFd(Errno),
51
52    #[cfg(target_family = "windows")]
53    EventFd(Error),
54
55    /// Already polling
56    EPollAlreadyPolling,
57
58    /// Can not convert time.
59    Conversion,
60
61    /// Some error which came from other crate.
62    ExternalError,
63
64    /// Duplicate record.
65    Duplicate,
66
67    /// Already polled
68    AlreadyPolled,
69
70    /// Item not found
71    NotFound,
72
73    /// Ticket got invalid
74    TicketInstanceGone,
75
76    /// Item belong to other instance
77    BelongOtherInstance,
78
79    /// MPSC channel disconnected.
80    ChannelDisconnected,
81
82    /// Thread poisoned
83    Poisoned,
84
85    SpawnError(ErrorKind),
86
87    ReferenceGone,
88
89    MpscTimeout,
90
91    ZeroRelativeTime,
92}
93
94impl fmt::Display for TimerErrorType
95{
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
97    {
98        match self
99        {
100            Self::Expired => 
101                write!(f, "absolute time has expired"),
102            #[cfg(target_family = "unix")]
103            Self::TimerError(e) => 
104                write!(f, "timer setup error: {}", e.desc()),
105            #[cfg(target_family = "windows")]
106            Self::TimerError(e) => 
107                write!(f, "timer setup error: {}", e.message()),
108            Self::QueueEmpty => 
109                write!(f, "the queue is empty"),
110            #[cfg(target_family = "unix")]
111            Self::EPoll(errno) => 
112                write!(f, "epoll() error: {}", errno.desc()),
113            #[cfg(target_family = "windows")]
114             Self::EPoll(errno) => 
115                write!(f, "epoll() error: {}", errno.message()),
116            #[cfg(target_family = "unix")]
117            Self::EventFd(errno) => 
118                write!(f, "eventfd() error: {}", errno.desc()),
119            #[cfg(target_family = "windows")]
120            Self::EventFd(errno) => 
121                write!(f, "eventfd() error: {}", errno.message()),
122            Self::EPollAlreadyPolling =>
123                write!(f, "other thread already polling"),
124            Self::Conversion => 
125                write!(f, "cannot convert time"),
126            Self::ExternalError => 
127                write!(f, "external error"),
128            Self::Duplicate => 
129                write!(f, "duplicate"),
130            Self::AlreadyPolled =>
131                write!(f, "instance is already on watch"),
132            Self::NotFound => 
133                write!(f, "not found"),
134            Self::TicketInstanceGone => 
135                write!(f, "ticket dropped"),
136            Self::BelongOtherInstance =>
137                write!(f, "item belongs to other instance"),
138            Self::ChannelDisconnected => 
139                write!(f, "MPSC sender has disconnected from receiver"),
140            Self::Poisoned =>
141                write!(f, "mutex poisoned"),
142            Self::SpawnError(e) =>
143                write!(f, "thread spawn error: {}", e),
144            Self::ReferenceGone =>
145                write!(f, "Weak reference gone"),
146            Self::MpscTimeout => 
147                write!(f, "MPSC timeout"),
148            Self::ZeroRelativeTime => 
149                write!(f, "The relative time for offset is zero.")
150        }
151    }
152}
153
154/// Error storage.
155#[derive(Debug, Clone)]
156pub struct TimerError
157{
158    /// Error code.
159    reason: TimerErrorType,
160
161    /// Error descrition.
162    msg: String
163}
164
165impl Eq for TimerError {}
166
167impl PartialEq for TimerError
168{
169    fn eq(&self, other: &Self) -> bool 
170    {
171        return self.reason == other.reason;
172    }
173}
174
175impl fmt::Display for TimerError
176{
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
178    {
179        write!(f, "{} {}", self.reason, self.msg)
180    }
181}
182
183impl TimerError
184{
185    pub 
186    fn new(reason: TimerErrorType, msg: String) -> Self
187    {
188        return Self{ reason, msg };
189    }
190
191    pub 
192    fn get_error_type(&self) -> TimerErrorType
193    {
194        return self.reason.clone();
195    }
196
197    pub 
198    fn get_error_msg(&self) -> &str
199    {
200        return &self.msg;
201    }
202}
203
204/// Alias for the [Result] used by timer queues.
205pub type TimerResult<R> = Result<R, TimerError>;
206
207#[macro_export]
208macro_rules! timer_err
209{
210    ($reason:expr,$($arg:tt)*) => (
211        return std::result::Result::Err( $crate::error::TimerError::new($reason, format!($($arg)*)) )
212    )
213}
214
215#[macro_export]
216macro_rules! map_timer_err
217{
218    ($reason:expr, $($arg:tt)*) => (
219        $crate::error::TimerError::new($reason, format!($($arg)*))
220    )
221}