use std::{
collections::HashMap,
sync::{Arc, RwLock},
time::{Duration, Instant},
};
use super::JwksCache;
#[derive(Debug)]
pub struct InMemoryCache {
storage: Arc<RwLock<HashMap<String, CacheEntry>>>,
}
#[derive(Debug, Clone)]
struct CacheEntry {
data: String,
expires_at: Instant,
}
impl Default for InMemoryCache {
fn default() -> Self {
Self::new()
}
}
impl InMemoryCache {
#[must_use]
pub fn new() -> Self {
Self {
storage: Arc::new(RwLock::new(HashMap::new())),
}
}
fn cleanup_expired(&self) {
if let Ok(mut storage) = self.storage.write() {
let now = Instant::now();
storage.retain(|_, entry| entry.expires_at > now);
}
}
}
impl JwksCache for InMemoryCache {
fn get(&self, key: &str) -> Option<String> {
self.cleanup_expired();
self.storage.read().map_or(None, |storage| {
storage
.get(key)
.filter(|entry| entry.expires_at > Instant::now())
.map(|entry| entry.data.clone())
})
}
fn set(&self, key: &str, value: String, ttl: Duration) {
if let Ok(mut storage) = self.storage.write() {
let entry = CacheEntry {
data: value,
expires_at: Instant::now() + ttl,
};
storage.insert(key.to_string(), entry);
}
}
}