clnrm_core/cache/cache_trait.rs
1//! Cache trait abstraction for pluggable backends
2//!
3//! Provides trait-based interface following London School TDD principles:
4//! - Clear contract definition through trait methods
5//! - Mockable interface for testing
6//! - Support for multiple backend implementations
7
8use crate::error::Result;
9use chrono::{DateTime, Utc};
10use std::path::{Path, PathBuf};
11
12/// Statistics about cache state
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct CacheStats {
15 /// Total number of files in cache
16 pub total_files: usize,
17 /// Last update timestamp
18 pub last_updated: DateTime<Utc>,
19 /// Cache file path (if applicable)
20 pub cache_path: Option<PathBuf>,
21}
22
23/// Cache trait defining the contract for cache backends
24///
25/// London School TDD:
26/// - This trait defines the collaboration contract
27/// - Implementations can be mocked for testing
28/// - Focuses on behavior verification over state
29///
30/// # Design Principles
31/// - All methods return Result for proper error handling
32/// - Thread-safe implementations required (Clone + Send + Sync)
33/// - No async to maintain dyn compatibility
34pub trait Cache: Send + Sync {
35 /// Check if a file has changed since last cache update
36 ///
37 /// # Arguments
38 /// * `file_path` - Path to the file being checked
39 /// * `rendered_content` - Current content to compare against cache
40 ///
41 /// # Returns
42 /// - Ok(true) if file changed or not in cache
43 /// - Ok(false) if file unchanged
44 /// - Err if operation fails
45 fn has_changed(&self, file_path: &Path, rendered_content: &str) -> Result<bool>;
46
47 /// Update cache with new file hash
48 ///
49 /// # Arguments
50 /// * `file_path` - Path to the file being updated
51 /// * `rendered_content` - Content to hash and store
52 fn update(&self, file_path: &Path, rendered_content: &str) -> Result<()>;
53
54 /// Remove a file from cache
55 ///
56 /// # Arguments
57 /// * `file_path` - Path to the file being removed
58 fn remove(&self, file_path: &Path) -> Result<()>;
59
60 /// Save cache to persistent storage (if applicable)
61 ///
62 /// For in-memory caches, this is a no-op
63 fn save(&self) -> Result<()>;
64
65 /// Get cache statistics
66 fn stats(&self) -> Result<CacheStats>;
67
68 /// Clear all cache entries
69 fn clear(&self) -> Result<()>;
70}
71
72/// Type alias for boxed cache trait object
73pub type BoxedCache = Box<dyn Cache>;