srv_rs/client/
cache.rs

1//! Caches for SRV record targets.
2
3use std::time::Instant;
4
5#[derive(Debug)]
6/// A cache of items valid for a limited period of time.
7pub struct Cache<T> {
8    valid_until: Instant,
9    items: Box<[T]>,
10}
11
12impl<T> Cache<T> {
13    /// Creates a new cache of items valid until some time.
14    pub fn new(items: impl Into<Box<[T]>>, valid_until: Instant) -> Self {
15        let items = items.into();
16        Self { valid_until, items }
17    }
18
19    /// Determines if a cache is valid.
20    pub fn valid(&self) -> bool {
21        !self.items.is_empty() && Instant::now() <= self.valid_until
22    }
23
24    /// Gets the items stored in a cache.
25    pub fn items(&self) -> &[T] {
26        &self.items
27    }
28}
29
30impl<T> Default for Cache<T> {
31    fn default() -> Self {
32        Self::new(Vec::new(), Instant::now())
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use std::time::Duration;
40
41    #[test]
42    fn default_is_invalid() {
43        assert!(!Cache::<()>::default().valid());
44    }
45
46    #[test]
47    fn empty_is_invalid() {
48        let cache = Cache::<()>::new(vec![], Instant::now() + Duration::from_secs(1));
49        assert!(!cache.valid());
50    }
51
52    #[test]
53    fn expired_is_invalid() {
54        let cache = Cache::new(vec![()], Instant::now() - Duration::from_secs(1));
55        assert!(!cache.valid());
56    }
57
58    #[test]
59    fn nonempty_and_fresh_is_valid() {
60        let cache = Cache::new(vec![()], Instant::now() + Duration::from_secs(1));
61        assert!(cache.valid());
62    }
63}