| 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 { |
| 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)] |
| 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. |
| 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 | |
| 88 | impl error::Error for Error {} |
| 89 | |
| 90 | impl fmt::Display for Error { |
| 91 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 92 | let descr: &'static 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 | |
| 105 | impl Elapsed { |
| 106 | pub(crate) fn new() -> Self { |
| 107 | Elapsed(()) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | impl fmt::Display for Elapsed { |
| 112 | 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 { |
| 120 | fn from(_err: Elapsed) -> std::io::Error { |
| 121 | std::io::ErrorKind::TimedOut.into() |
| 122 | } |
| 123 | } |
| 124 | |