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