leptos_sync_core/reliability/data_integrity/
version.rs1use super::super::IntegrityError;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct VersionConfig {
10 pub verify_on_read: bool,
12 pub increment_on_write: bool,
14 pub max_version_diff: u64,
16}
17
18impl Default for VersionConfig {
19 fn default() -> Self {
20 Self {
21 verify_on_read: true,
22 increment_on_write: true,
23 max_version_diff: 1,
24 }
25 }
26}
27
28#[derive(Debug, Clone)]
30pub struct VersionVerifier {
31 config: VersionConfig,
33 versions: HashMap<String, u64>,
35}
36
37impl VersionVerifier {
38 pub fn new() -> Self {
40 Self {
41 config: VersionConfig::default(),
42 versions: HashMap::new(),
43 }
44 }
45
46 pub fn with_config(config: VersionConfig) -> Self {
48 Self {
49 config,
50 versions: HashMap::new(),
51 }
52 }
53
54 pub fn get_version(&self, key: &str) -> u64 {
56 self.versions.get(key).copied().unwrap_or(0)
57 }
58
59 pub fn increment_version(&mut self, key: &str) -> u64 {
61 let current_version = self.get_version(key);
62 let new_version = current_version + 1;
63 self.versions.insert(key.to_string(), new_version);
64 new_version
65 }
66
67 pub fn verify_version(&self, key: &str, expected_version: u64) -> Result<bool, IntegrityError> {
69 let current_version = self.get_version(key);
70 let version_diff = if current_version > expected_version {
71 current_version - expected_version
72 } else {
73 expected_version - current_version
74 };
75
76 if version_diff > self.config.max_version_diff {
77 return Err(IntegrityError::VersionMismatch {
78 key: key.to_string(),
79 expected: expected_version,
80 actual: current_version,
81 });
82 }
83
84 Ok(true)
85 }
86
87 pub fn set_version(&mut self, key: &str, version: u64) {
89 self.versions.insert(key.to_string(), version);
90 }
91
92 pub fn remove_version(&mut self, key: &str) {
94 self.versions.remove(key);
95 }
96
97 pub fn get_all_versions(&self) -> &HashMap<String, u64> {
99 &self.versions
100 }
101
102 pub fn clear_versions(&mut self) {
104 self.versions.clear();
105 }
106
107 pub fn config(&self) -> &VersionConfig {
109 &self.config
110 }
111}
112
113impl Default for VersionVerifier {
114 fn default() -> Self {
115 Self::new()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_version_verifier_creation() {
125 let verifier = VersionVerifier::new();
126 assert!(verifier.config().verify_on_read);
127 assert!(verifier.config().increment_on_write);
128 assert_eq!(verifier.config().max_version_diff, 1);
129 }
130
131 #[test]
132 fn test_version_verifier_with_config() {
133 let config = VersionConfig {
134 verify_on_read: false,
135 increment_on_write: true,
136 max_version_diff: 5,
137 };
138 let verifier = VersionVerifier::with_config(config.clone());
139 assert!(!verifier.config().verify_on_read);
140 assert!(verifier.config().increment_on_write);
141 assert_eq!(verifier.config().max_version_diff, 5);
142 }
143
144 #[test]
145 fn test_get_version() {
146 let verifier = VersionVerifier::new();
147 assert_eq!(verifier.get_version("test_key"), 0);
148 }
149
150 #[test]
151 fn test_increment_version() {
152 let mut verifier = VersionVerifier::new();
153 let key = "test_key";
154
155 assert_eq!(verifier.get_version(key), 0);
156 assert_eq!(verifier.increment_version(key), 1);
157 assert_eq!(verifier.get_version(key), 1);
158 assert_eq!(verifier.increment_version(key), 2);
159 assert_eq!(verifier.get_version(key), 2);
160 }
161
162 #[test]
163 fn test_verify_version() {
164 let mut verifier = VersionVerifier::new();
165 let key = "test_key";
166
167 verifier.set_version(key, 5);
169
170 assert!(verifier.verify_version(key, 5).unwrap());
172
173 assert!(verifier.verify_version(key, 4).unwrap());
175 assert!(verifier.verify_version(key, 6).unwrap());
176
177 assert!(verifier.verify_version(key, 3).is_err());
179 assert!(verifier.verify_version(key, 7).is_err());
180 }
181
182 #[test]
183 fn test_set_version() {
184 let mut verifier = VersionVerifier::new();
185 let key = "test_key";
186
187 verifier.set_version(key, 42);
188 assert_eq!(verifier.get_version(key), 42);
189 }
190
191 #[test]
192 fn test_remove_version() {
193 let mut verifier = VersionVerifier::new();
194 let key = "test_key";
195
196 verifier.set_version(key, 5);
197 assert_eq!(verifier.get_version(key), 5);
198
199 verifier.remove_version(key);
200 assert_eq!(verifier.get_version(key), 0);
201 }
202
203 #[test]
204 fn test_clear_versions() {
205 let mut verifier = VersionVerifier::new();
206
207 verifier.set_version("key1", 1);
208 verifier.set_version("key2", 2);
209 assert_eq!(verifier.get_all_versions().len(), 2);
210
211 verifier.clear_versions();
212 assert_eq!(verifier.get_all_versions().len(), 0);
213 }
214}