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