1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct CacheEntry {
9 pub version: String,
11
12 pub key: String,
14
15 pub namespace: String,
17
18 pub value: String,
20
21 pub metadata: CacheMetadata,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct CacheMetadata {
28 pub created_at: DateTime<Utc>,
30
31 pub last_accessed: DateTime<Utc>,
33
34 pub access_count: usize,
36
37 pub input_size: usize,
39
40 pub value_size: usize,
42}
43
44impl CacheEntry {
45 pub fn new(
47 version: String,
48 namespace: String,
49 key: String,
50 value: String,
51 input_size: usize,
52 ) -> Self {
53 let now = Utc::now();
54 let value_size = value.len();
55
56 Self {
57 version,
58 key,
59 namespace,
60 value,
61 metadata: CacheMetadata {
62 created_at: now,
63 last_accessed: now,
64 access_count: 0,
65 input_size,
66 value_size,
67 },
68 }
69 }
70
71 pub fn record_access(&mut self) {
73 self.metadata.last_accessed = Utc::now();
74 self.metadata.access_count += 1;
75 }
76
77 pub fn age_days(&self) -> i64 {
79 let now = Utc::now();
80 (now - self.metadata.created_at).num_days()
81 }
82
83 pub fn idle_days(&self) -> i64 {
85 let now = Utc::now();
86 (now - self.metadata.last_accessed).num_days()
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_cache_entry_creation() {
96 let entry = CacheEntry::new(
97 "1.0.0".to_string(),
98 "my-ns".to_string(),
99 "abc123".to_string(),
100 "test value".to_string(),
101 100,
102 );
103
104 assert_eq!(entry.version, "1.0.0");
105 assert_eq!(entry.namespace, "my-ns");
106 assert_eq!(entry.key, "abc123");
107 assert_eq!(entry.value, "test value");
108 assert_eq!(entry.metadata.access_count, 0);
109 assert_eq!(entry.metadata.input_size, 100);
110 assert_eq!(entry.metadata.value_size, 10);
111 }
112
113 #[test]
114 fn test_record_access() {
115 let mut entry = CacheEntry::new(
116 "1.0.0".to_string(),
117 "ns".to_string(),
118 "abc123".to_string(),
119 "test".to_string(),
120 100,
121 );
122
123 assert_eq!(entry.metadata.access_count, 0);
124
125 entry.record_access();
126 assert_eq!(entry.metadata.access_count, 1);
127
128 entry.record_access();
129 assert_eq!(entry.metadata.access_count, 2);
130 }
131
132 #[test]
133 fn test_idle_days_returns_actual_value() {
134 let mut entry = CacheEntry::new(
135 "1.0.0".to_string(),
136 "ns".to_string(),
137 "abc123".to_string(),
138 "test".to_string(),
139 10,
140 );
141
142 assert_eq!(entry.idle_days(), 0);
143
144 entry.metadata.last_accessed = Utc::now() - chrono::Duration::days(5);
145 assert_eq!(entry.idle_days(), 5);
146
147 entry.metadata.last_accessed = Utc::now() - chrono::Duration::days(100);
148 assert_eq!(entry.idle_days(), 100);
149 }
150
151 #[test]
152 fn test_age_days_returns_actual_value() {
153 let mut entry = CacheEntry::new(
154 "1.0.0".to_string(),
155 "ns".to_string(),
156 "abc123".to_string(),
157 "test".to_string(),
158 10,
159 );
160
161 assert_eq!(entry.age_days(), 0);
162
163 entry.metadata.created_at = Utc::now() - chrono::Duration::days(10);
164 assert_eq!(entry.age_days(), 10);
165 }
166}