use std::time::Duration;
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub enum CacheStrategy {
Fresh,
#[default]
Refresh,
Invalidate,
Bypass,
}
impl std::fmt::Display for CacheStrategy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CacheStrategy::Fresh => write!(f, "Fresh"),
CacheStrategy::Refresh => write!(f, "Refresh"),
CacheStrategy::Invalidate => write!(f, "Invalidate"),
CacheStrategy::Bypass => write!(f, "Bypass"),
}
}
}
#[derive(Clone, Debug)]
pub struct CacheContext {
pub key: String,
pub is_cached: bool,
pub ttl_remaining: Option<Duration>,
pub cached_at: Option<std::time::Instant>,
pub metadata: std::collections::HashMap<String, String>,
}
impl CacheContext {
pub fn new(key: String) -> Self {
CacheContext {
key,
is_cached: false,
ttl_remaining: None,
cached_at: None,
metadata: std::collections::HashMap::new(),
}
}
pub fn with_cached(mut self, is_cached: bool) -> Self {
self.is_cached = is_cached;
self
}
pub fn with_ttl(mut self, ttl: Duration) -> Self {
self.ttl_remaining = Some(ttl);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strategy_display() {
assert_eq!(CacheStrategy::Fresh.to_string(), "Fresh");
assert_eq!(CacheStrategy::Refresh.to_string(), "Refresh");
assert_eq!(CacheStrategy::Invalidate.to_string(), "Invalidate");
assert_eq!(CacheStrategy::Bypass.to_string(), "Bypass");
}
#[test]
fn test_strategy_default() {
assert_eq!(CacheStrategy::default(), CacheStrategy::Refresh);
}
#[test]
fn test_strategy_equality() {
assert_eq!(CacheStrategy::Fresh, CacheStrategy::Fresh);
assert_ne!(CacheStrategy::Fresh, CacheStrategy::Refresh);
}
#[test]
fn test_cache_context_builder() {
let ctx = CacheContext::new("test_key".to_string())
.with_cached(true)
.with_ttl(Duration::from_secs(300));
assert_eq!(ctx.key, "test_key");
assert!(ctx.is_cached);
assert_eq!(ctx.ttl_remaining, Some(Duration::from_secs(300)));
}
}