gioser

tawasuyu/brahman

Rust 334TOML 129Markdown 39JSON 174745 Sutichaykuna

⎇ 545dd59c727b2c6b9752ab4b29de64ad0d24b35c crates/runtime/sandokan-lifecycle/src/ttl.rs Rust · 57 siq'ikuna · 1.5 KB Ñawpa willay Pi imata llamkarqan ch'uya

feat(sandokan-lifecycle): A4 — primitivas de lifecycle agnósticas 545dd59c7 · sergio ·

1//! Time-to-live anclado a un `Instant`.
2
3use std::time::{Duration, Instant};
4
5/// Time-to-live. Marca un instante límite tras el cual una entidad
6/// supervisada se considera vencida. Runtime-only (no serializable:
7/// `Instant` no tiene representación estable).
8#[derive(Debug, Clone, Copy)]
9pub struct Ttl {
10    deadline: Instant,
11}
12
13impl Ttl {
14    /// TTL que vence `lifetime` después de ahora.
15    pub fn new(lifetime: Duration) -> Self {
16        Self { deadline: Instant::now() + lifetime }
17    }
18
19    /// TTL con un deadline absoluto explícito.
20    pub fn from_deadline(deadline: Instant) -> Self {
21        Self { deadline }
22    }
23
24    /// `true` si el deadline ya pasó.
25    pub fn expired(&self) -> bool {
26        Instant::now() >= self.deadline
27    }
28
29    /// Tiempo restante hasta el deadline. `Duration::ZERO` si ya venció.
30    pub fn remaining(&self) -> Duration {
31        self.deadline.saturating_duration_since(Instant::now())
32    }
33
34    /// El instante límite.
35    pub fn deadline(&self) -> Instant {
36        self.deadline
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn fresh_ttl_not_expired() {
46        let t = Ttl::new(Duration::from_secs(60));
47        assert!(!t.expired());
48        assert!(t.remaining() > Duration::from_secs(58));
49    }
50
51    #[test]
52    fn past_deadline_is_expired() {
53        let t = Ttl::from_deadline(Instant::now() - Duration::from_secs(1));
54        assert!(t.expired());
55        assert_eq!(t.remaining(), Duration::ZERO);
56    }
57}