1use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct CatalogVersion {
12 pub id: Uuid,
13 pub catalog_id: Uuid,
14 pub version: String,
15 pub description: Option<String>,
16 pub created_at: DateTime<Utc>,
17 pub created_by: Option<Uuid>,
18 pub is_active: bool,
19 pub is_published: bool,
20 pub published_at: Option<DateTime<Utc>>,
21 pub metadata: Option<serde_json::Value>,
22}
23
24pub struct VersionManager {
26 versions: Vec<CatalogVersion>,
27}
28
29impl VersionManager {
30 pub fn new() -> Self {
32 Self {
33 versions: Vec::new(),
34 }
35 }
36
37 pub fn create_version(
39 &mut self,
40 catalog_id: Uuid,
41 version: String,
42 description: Option<String>,
43 created_by: Option<Uuid>,
44 ) -> CatalogVersion {
45 let catalog_version = CatalogVersion {
46 id: Uuid::new_v4(),
47 catalog_id,
48 version,
49 description,
50 created_at: Utc::now(),
51 created_by,
52 is_active: false,
53 is_published: false,
54 published_at: None,
55 metadata: None,
56 };
57 self.versions.push(catalog_version.clone());
58 catalog_version
59 }
60
61 pub fn publish_version(&mut self, version_id: Uuid) -> Result<(), String> {
63 let catalog_id = {
64 let version = self
65 .versions
66 .iter()
67 .find(|v| v.id == version_id)
68 .ok_or_else(|| "Version not found".to_string())?
69 .catalog_id;
70 version
71 };
72
73 for v in self.versions.iter_mut() {
75 if v.catalog_id == catalog_id && v.id != version_id {
76 v.is_active = false;
77 }
78 }
79
80 if let Some(version) = self.versions.iter_mut().find(|v| v.id == version_id) {
82 version.is_active = true;
83 version.is_published = true;
84 version.published_at = Some(Utc::now());
85 }
86
87 Ok(())
88 }
89
90 pub fn rollback_to_version(&mut self, version_id: Uuid) -> Result<(), String> {
92 self.publish_version(version_id)
93 }
94
95 pub fn get_active_version(&self, catalog_id: Uuid) -> Option<&CatalogVersion> {
97 self.versions
98 .iter()
99 .find(|v| v.catalog_id == catalog_id && v.is_active)
100 }
101
102 pub fn get_versions(&self, catalog_id: Uuid) -> Vec<&CatalogVersion> {
104 self.versions
105 .iter()
106 .filter(|v| v.catalog_id == catalog_id)
107 .collect()
108 }
109
110 pub fn compare_versions(
112 &self,
113 version_id_1: Uuid,
114 version_id_2: Uuid,
115 ) -> Result<VersionDiff, String> {
116 let v1 = self
117 .versions
118 .iter()
119 .find(|v| v.id == version_id_1)
120 .ok_or_else(|| "Version 1 not found".to_string())?;
121 let v2 = self
122 .versions
123 .iter()
124 .find(|v| v.id == version_id_2)
125 .ok_or_else(|| "Version 2 not found".to_string())?;
126
127 Ok(VersionDiff {
128 version_1: v1.clone(),
129 version_2: v2.clone(),
130 differences: vec![], })
132 }
133}
134
135impl Default for VersionManager {
136 fn default() -> Self {
137 Self::new()
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct VersionDiff {
144 pub version_1: CatalogVersion,
145 pub version_2: CatalogVersion,
146 pub differences: Vec<String>,
147}