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