1use std::time::{Duration, Instant as MonotonicInstant};
2
3#[derive(Clone, Copy, Debug)]
12pub(crate) struct Expiration(Option<MonotonicInstant>);
13
14impl Expiration {
15 pub(crate) fn after(ttl: Duration) -> Expiration {
18 Expiration(
19 crate::now::monotonic_time().and_then(|now| now.checked_add(ttl)),
20 )
21 }
22
23 pub(crate) const fn expired() -> Expiration {
25 Expiration(None)
26 }
27
28 pub(crate) fn is_expired(self) -> bool {
30 self.0.map_or(true, |t| {
31 let Some(now) = crate::now::monotonic_time() else { return true };
32 now > t
33 })
34 }
35}
36
37impl core::fmt::Display for Expiration {
38 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
39 let Some(instant) = self.0 else {
40 return write!(f, "expired");
41 };
42 let Some(now) = crate::now::monotonic_time() else {
43 return write!(f, "expired");
44 };
45 let Some(duration) = instant.checked_duration_since(now) else {
46 return write!(f, "expired");
47 };
48 write!(f, "{duration:?}")
49 }
50}