1 //! Time error types.
2 
3 use std::error;
4 use std::fmt;
5 
6 /// Errors encountered by the timer implementation.
7 ///
8 /// Currently, there are two different errors that can occur:
9 ///
10 /// * `shutdown` occurs when a timer operation is attempted, but the timer
11 ///   instance has been dropped. In this case, the operation will never be able
12 ///   to complete and the `shutdown` error is returned. This is a permanent
13 ///   error, i.e., once this error is observed, timer operations will never
14 ///   succeed in the future.
15 ///
16 /// * `at_capacity` occurs when a timer operation is attempted, but the timer
17 ///   instance is currently handling its maximum number of outstanding sleep instances.
18 ///   In this case, the operation is not able to be performed at the current
19 ///   moment, and `at_capacity` is returned. This is a transient error, i.e., at
20 ///   some point in the future, if the operation is attempted again, it might
21 ///   succeed. Callers that observe this error should attempt to [shed load]. One
22 ///   way to do this would be dropping the future that issued the timer operation.
23 ///
24 /// [shed load]: https://en.wikipedia.org/wiki/Load_Shedding
25 #[derive(Debug, Copy, Clone)]
26 pub struct Error(Kind);
27 
28 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
29 #[repr(u8)]
30 pub(crate) enum Kind {
31     Shutdown = 1,
32     AtCapacity = 2,
33     Invalid = 3,
34 }
35 
36 impl From<Kind> for Error {
from(k: Kind) -> Self37     fn from(k: Kind) -> Self {
38         Error(k)
39     }
40 }
41 
42 /// Errors returned by `Timeout`.
43 ///
44 /// This error is returned when a timeout expires before the function was able
45 /// to finish.
46 #[derive(Debug, PartialEq, Eq)]
47 pub struct Elapsed(());
48 
49 #[derive(Debug)]
50 pub(crate) enum InsertError {
51     Elapsed,
52 }
53 
54 // ===== impl Error =====
55 
56 impl Error {
57     /// Creates an error representing a shutdown timer.
shutdown() -> Error58     pub fn shutdown() -> Error {
59         Error(Kind::Shutdown)
60     }
61 
62     /// Returns `true` if the error was caused by the timer being shutdown.
is_shutdown(&self) -> bool63     pub fn is_shutdown(&self) -> bool {
64         matches!(self.0, Kind::Shutdown)
65     }
66 
67     /// Creates an error representing a timer at capacity.
at_capacity() -> Error68     pub fn at_capacity() -> Error {
69         Error(Kind::AtCapacity)
70     }
71 
72     /// Returns `true` if the error was caused by the timer being at capacity.
is_at_capacity(&self) -> bool73     pub fn is_at_capacity(&self) -> bool {
74         matches!(self.0, Kind::AtCapacity)
75     }
76 
77     /// Creates an error representing a misconfigured timer.
invalid() -> Error78     pub fn invalid() -> Error {
79         Error(Kind::Invalid)
80     }
81 
82     /// Returns `true` if the error was caused by the timer being misconfigured.
is_invalid(&self) -> bool83     pub fn is_invalid(&self) -> bool {
84         matches!(self.0, Kind::Invalid)
85     }
86 }
87 
88 impl error::Error for Error {}
89 
90 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result91     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
92         let descr = match self.0 {
93             Kind::Shutdown => {
94                 "the timer is shutdown, must be called from the context of Tokio runtime"
95             }
96             Kind::AtCapacity => "timer is at capacity and cannot create a new entry",
97             Kind::Invalid => "timer duration exceeds maximum duration",
98         };
99         write!(fmt, "{descr}")
100     }
101 }
102 
103 // ===== impl Elapsed =====
104 
105 impl Elapsed {
new() -> Self106     pub(crate) fn new() -> Self {
107         Elapsed(())
108     }
109 }
110 
111 impl fmt::Display for Elapsed {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result112     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
113         "deadline has elapsed".fmt(fmt)
114     }
115 }
116 
117 impl std::error::Error for Elapsed {}
118 
119 impl From<Elapsed> for std::io::Error {
from(_err: Elapsed) -> std::io::Error120     fn from(_err: Elapsed) -> std::io::Error {
121         std::io::ErrorKind::TimedOut.into()
122     }
123 }
124