use std::time::Instant;
#[derive(Debug)]
pub struct Cache<T> {
valid_until: Instant,
items: Box<[T]>,
}
impl<T> Cache<T> {
pub fn new(items: impl Into<Box<[T]>>, valid_until: Instant) -> Self {
let items = items.into();
Self { valid_until, items }
}
pub fn valid(&self) -> bool {
!self.items.is_empty() && Instant::now() <= self.valid_until
}
pub fn items(&self) -> &[T] {
&self.items
}
}
impl<T> Default for Cache<T> {
fn default() -> Self {
Self::new(Vec::new(), Instant::now())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn default_is_invalid() {
assert!(!Cache::<()>::default().valid());
}
#[test]
fn empty_is_invalid() {
let cache = Cache::<()>::new(vec![], Instant::now() + Duration::from_secs(1));
assert!(!cache.valid());
}
#[test]
fn expired_is_invalid() {
let cache = Cache::new(vec![()], Instant::now() - Duration::from_secs(1));
assert!(!cache.valid());
}
#[test]
fn nonempty_and_fresh_is_valid() {
let cache = Cache::new(vec![()], Instant::now() + Duration::from_secs(1));
assert!(cache.valid());
}
}