use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheConfig {
pub max_entries_per_key: usize,
pub max_total_entries: usize,
pub eviction_policy: EvictionPolicy,
pub persistence: PersistenceConfig,
#[cfg(feature = "compression")]
pub compression: Option<CompressionConfig>,
pub default_ttl: Option<Duration>,
#[cfg(feature = "metrics")]
pub enable_metrics: bool,
}
impl Default for CacheConfig {
fn default() -> Self {
Self {
max_entries_per_key: 100,
max_total_entries: 10_000,
eviction_policy: EvictionPolicy::Lru,
persistence: PersistenceConfig::default(),
#[cfg(feature = "compression")]
compression: None,
default_ttl: None,
#[cfg(feature = "metrics")]
enable_metrics: false,
}
}
}
impl CacheConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_max_entries_per_key(mut self, max: usize) -> Self {
self.max_entries_per_key = max;
self
}
pub fn with_max_total_entries(mut self, max: usize) -> Self {
self.max_total_entries = max;
self
}
pub fn with_eviction_policy(mut self, policy: EvictionPolicy) -> Self {
self.eviction_policy = policy;
self
}
pub fn with_persistence(mut self, persistence: PersistenceConfig) -> Self {
self.persistence = persistence;
self
}
pub fn with_default_ttl(mut self, ttl: Duration) -> Self {
self.default_ttl = Some(ttl);
self
}
#[cfg(feature = "compression")]
pub fn with_compression(mut self, compression: CompressionConfig) -> Self {
self.compression = Some(compression);
self
}
#[cfg(feature = "metrics")]
pub fn with_metrics(mut self, enable: bool) -> Self {
self.enable_metrics = enable;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EvictionPolicy {
Lru,
Lfu,
Fifo,
Ttl,
None,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersistenceConfig {
pub enabled: bool,
pub path: Option<PathBuf>,
pub sync_interval: usize,
pub save_on_drop: bool,
pub load_on_startup: bool,
}
impl Default for PersistenceConfig {
fn default() -> Self {
Self {
enabled: false,
path: None,
sync_interval: 100,
save_on_drop: true,
load_on_startup: true,
}
}
}
impl PersistenceConfig {
pub fn with_path<P: Into<PathBuf>>(path: P) -> Self {
Self {
enabled: true,
path: Some(path.into()),
..Default::default()
}
}
pub fn disabled() -> Self {
Self {
enabled: false,
..Default::default()
}
}
}
#[cfg(feature = "compression")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompressionConfig {
pub algorithm: CompressionAlgorithm,
pub level: u32,
pub min_size: usize,
}
#[cfg(feature = "compression")]
impl Default for CompressionConfig {
fn default() -> Self {
Self {
algorithm: CompressionAlgorithm::Gzip,
level: 6,
min_size: 1024, }
}
}
#[cfg(feature = "compression")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CompressionAlgorithm {
Gzip,
Zlib,
Deflate,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = CacheConfig::default();
assert_eq!(config.max_entries_per_key, 100);
assert_eq!(config.max_total_entries, 10_000);
assert_eq!(config.eviction_policy, EvictionPolicy::Lru);
assert!(!config.persistence.enabled);
}
#[test]
fn test_config_builder() {
let config = CacheConfig::new()
.with_max_entries_per_key(50)
.with_max_total_entries(5000)
.with_eviction_policy(EvictionPolicy::Lfu)
.with_default_ttl(Duration::from_secs(300));
assert_eq!(config.max_entries_per_key, 50);
assert_eq!(config.max_total_entries, 5000);
assert_eq!(config.eviction_policy, EvictionPolicy::Lfu);
assert_eq!(config.default_ttl, Some(Duration::from_secs(300)));
}
#[test]
fn test_persistence_config() {
let persistence = PersistenceConfig::with_path("/tmp/cache");
assert!(persistence.enabled);
assert_eq!(persistence.path, Some(PathBuf::from("/tmp/cache")));
assert_eq!(persistence.sync_interval, 100);
assert!(persistence.save_on_drop);
assert!(persistence.load_on_startup);
}
#[cfg(feature = "compression")]
#[test]
fn test_compression_config() {
let compression = CompressionConfig::default();
assert_eq!(compression.algorithm, CompressionAlgorithm::Gzip);
assert_eq!(compression.level, 6);
assert_eq!(compression.min_size, 1024);
}
}