1//! Time error types.
2
3use std::error;
4use 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)]
26pub struct Error(Kind);
27
28#[derive(Debug, Clone, Copy, Eq, PartialEq)]
29#[repr(u8)]
30pub(crate) enum Kind {
31 Shutdown = 1,
32 AtCapacity = 2,
33 Invalid = 3,
34}
35
36impl From<Kind> for Error {
37 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)]
47pub struct Elapsed(());
48
49#[derive(Debug)]
50pub(crate) enum InsertError {
51 Elapsed,
52}
53
54// ===== impl Error =====
55
56impl Error {
57 /// Creates an error representing a shutdown timer.
58 pub fn shutdown() -> Error {
59 Error(Kind::Shutdown)
60 }
61
62 /// Returns `true` if the error was caused by the timer being shutdown.
63 pub fn is_shutdown(&self) -> bool {
64 matches!(self.0, Kind::Shutdown)
65 }
66
67 /// Creates an error representing a timer at capacity.
68 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.
73 pub fn is_at_capacity(&self) -> bool {
74 matches!(self.0, Kind::AtCapacity)
75 }
76
77 /// Creates an error representing a misconfigured timer.
78 pub fn invalid() -> Error {
79 Error(Kind::Invalid)
80 }
81
82 /// Returns `true` if the error was caused by the timer being misconfigured.
83 pub fn is_invalid(&self) -> bool {
84 matches!(self.0, Kind::Invalid)
85 }
86}
87
88impl error::Error for Error {}
89
90impl fmt::Display for Error {
91 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
92 let descr: &str = 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
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