use std::ops::Deref;
use std::time::{Duration, SystemTime};
use crate::Error;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CacheEntry<V> {
value: V,
cached_at: Option<SystemTime>,
ttl: Option<Duration>,
}
impl<V> CacheEntry<V> {
pub fn new(value: V) -> Self {
Self {
value,
cached_at: None,
ttl: None,
}
}
pub fn expires_after(value: V, ttl: Duration) -> Self {
Self {
value,
cached_at: None,
ttl: Some(ttl),
}
}
pub fn expires_at(value: V, ttl: Duration, cached_at: SystemTime) -> Self {
Self {
value,
cached_at: Some(cached_at),
ttl: Some(ttl),
}
}
#[must_use]
pub fn cached_at(&self) -> Option<SystemTime> {
self.cached_at
}
pub fn ensure_cached_at(&mut self, cached_at: SystemTime) {
if self.cached_at.is_none() {
self.cached_at = Some(cached_at);
}
}
#[must_use]
pub fn ttl(&self) -> Option<Duration> {
self.ttl
}
pub fn set_ttl(&mut self, ttl: Duration) {
self.ttl = Some(ttl);
}
#[must_use]
pub fn into_value(self) -> V {
self.value
}
#[must_use]
pub fn value(&self) -> &V {
&self.value
}
pub fn try_map_value<U, F: FnOnce(V) -> Result<U, Error>>(self, f: F) -> Result<CacheEntry<U>, Error> {
Ok(CacheEntry {
value: f(self.value)?,
cached_at: self.cached_at,
ttl: self.ttl,
})
}
}
impl<V> Deref for CacheEntry<V> {
type Target = V;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<V> From<V> for CacheEntry<V> {
fn from(value: V) -> Self {
Self::new(value)
}
}