1use std::time::Instant;
4
5#[derive(Debug)]
6pub struct Cache<T> {
8 valid_until: Instant,
9 items: Box<[T]>,
10}
11
12impl<T> Cache<T> {
13 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 pub fn valid(&self) -> bool {
21 !self.items.is_empty() && Instant::now() <= self.valid_until
22 }
23
24 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}