agentic_evolve_core/storage/
versioner.rs1use std::collections::HashMap;
4
5use crate::types::error::{EvolveError, EvolveResult};
6use crate::types::pattern::Pattern;
7
8#[derive(Debug, Clone)]
10pub struct VersionEntry {
11 pub version: u32,
12 pub pattern_snapshot: String, pub created_at: i64,
14 pub change_description: String,
15}
16
17#[derive(Debug, Default)]
19pub struct PatternVersioner {
20 history: HashMap<String, Vec<VersionEntry>>,
21}
22
23impl PatternVersioner {
24 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn record_version(&mut self, pattern: &Pattern, description: &str) -> EvolveResult<u32> {
29 let snapshot = serde_json::to_string(pattern)
30 .map_err(|e| EvolveError::SerializationError(e.to_string()))?;
31 let entry = VersionEntry {
32 version: pattern.version,
33 pattern_snapshot: snapshot,
34 created_at: chrono::Utc::now().timestamp(),
35 change_description: description.to_string(),
36 };
37 self.history
38 .entry(pattern.id.as_str().to_string())
39 .or_default()
40 .push(entry);
41 Ok(pattern.version)
42 }
43
44 pub fn get_history(&self, pattern_id: &str) -> Vec<&VersionEntry> {
45 self.history
46 .get(pattern_id)
47 .map(|entries| entries.iter().collect())
48 .unwrap_or_default()
49 }
50
51 pub fn get_version(&self, pattern_id: &str, version: u32) -> EvolveResult<&VersionEntry> {
52 let entries = self
53 .history
54 .get(pattern_id)
55 .ok_or_else(|| EvolveError::PatternNotFound(pattern_id.to_string()))?;
56 entries
57 .iter()
58 .find(|e| e.version == version)
59 .ok_or_else(|| EvolveError::PatternNotFound(format!("{pattern_id}@v{version}")))
60 }
61
62 pub fn latest_version(&self, pattern_id: &str) -> Option<u32> {
63 self.history
64 .get(pattern_id)
65 .and_then(|entries| entries.last())
66 .map(|e| e.version)
67 }
68
69 pub fn total_versions(&self) -> usize {
70 self.history.values().map(|v| v.len()).sum()
71 }
72
73 pub fn clear(&mut self) {
74 self.history.clear();
75 }
76}