1//! Time error types.
2
3use self::Kind::*;
4use std::error;
5use 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)]
27pub struct Error(Kind);
28
29#[derive(Debug, Clone, Copy, Eq, PartialEq)]
30#[repr(u8)]
31pub(crate) enum Kind {
32 Shutdown = 1,
33 AtCapacity = 2,
34 Invalid = 3,
35}
36
37impl From<Kind> for Error {
38 fn from(k: Kind) -> Self {
39 Error(k)
40 }
41}
42
43/// Errors returned by `Timeout`.
44///
45/// This error is returned when a timeout expires before the function was able
46/// to finish.
47#[derive(Debug, PartialEq, Eq)]
48pub struct Elapsed(());
49
50#[derive(Debug)]
51pub(crate) enum InsertError {
52 Elapsed,
53}
54
55// ===== impl Error =====
56
57impl Error {
58 /// Creates an error representing a shutdown timer.
59 pub fn shutdown() -> Error {
60 Error(Shutdown)
61 }
62
63 /// Returns `true` if the error was caused by the timer being shutdown.
64 pub fn is_shutdown(&self) -> bool {
65 matches!(self.0, Kind::Shutdown)
66 }
67
68 /// Creates an error representing a timer at capacity.
69 pub fn at_capacity() -> Error {
70 Error(AtCapacity)
71 }
72
73 /// Returns `true` if the error was caused by the timer being at capacity.
74 pub fn is_at_capacity(&self) -> bool {
75 matches!(self.0, Kind::AtCapacity)
76 }
77
78 /// Creates an error representing a misconfigured timer.
79 pub fn invalid() -> Error {
80 Error(Invalid)
81 }
82
83 /// Returns `true` if the error was caused by the timer being misconfigured.
84 pub fn is_invalid(&self) -> bool {
85 matches!(self.0, Kind::Invalid)
86 }
87}
88
89impl error::Error for Error {}
90
91impl fmt::Display for Error {
92 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
93 use self::Kind::*;
94 let descr: &str = match self.0 {
95 Shutdown => "the timer is shutdown, must be called from the context of Tokio runtime",
96 AtCapacity => "timer is at capacity and cannot create a new entry",
97 Invalid => "timer duration exceeds maximum duration",
98 };
99 write!(fmt, "{}", descr)
100 }
101}
102
103// ===== impl Elapsed =====
104
105impl Elapsed {
106 pub(crate) fn new() -> Self {
107 Elapsed(())
108 }
109}
110
111impl fmt::Display for Elapsed {
112 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
113 "deadline has elapsed".fmt(fmt)
114 }
115}
116
117impl std::error::Error for Elapsed {}
118
119impl From<Elapsed> for std::io::Error {
120 fn from(_err: Elapsed) -> std::io::Error {
121 std::io::ErrorKind::TimedOut.into()
122 }
123}
124