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