sea_core/
semantic_version.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
4pub struct SemanticVersion {
5 pub major: u32,
6 pub minor: u32,
7 pub patch: u32,
8}
9
10impl SemanticVersion {
11 pub fn new(major: u32, minor: u32, patch: u32) -> Self {
12 Self {
13 major,
14 minor,
15 patch,
16 }
17 }
18
19 pub fn parse(s: &str) -> Result<Self, String> {
20 let parts: Vec<&str> = s.split('.').collect();
21 if parts.len() != 3 {
22 return Err("Version must be in format major.minor.patch".to_string());
23 }
24
25 Ok(Self {
26 major: parts[0]
27 .parse()
28 .map_err(|_| "Invalid major version".to_string())?,
29 minor: parts[1]
30 .parse()
31 .map_err(|_| "Invalid minor version".to_string())?,
32 patch: parts[2]
33 .parse()
34 .map_err(|_| "Invalid patch version".to_string())?,
35 })
36 }
37
38 pub fn bump_major(&mut self) {
39 self.major += 1;
40 self.minor = 0;
41 self.patch = 0;
42 }
43
44 pub fn bump_minor(&mut self) {
45 self.minor += 1;
46 self.patch = 0;
47 }
48
49 pub fn bump_patch(&mut self) {
50 self.patch += 1;
51 }
52}
53
54impl std::fmt::Display for SemanticVersion {
55 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
56 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
57 }
58}
59
60impl Default for SemanticVersion {
61 fn default() -> Self {
62 Self::new(1, 0, 0)
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_semantic_version_parsing() {
72 let v = SemanticVersion::parse("1.2.3").unwrap();
73 assert_eq!(v.major, 1);
74 assert_eq!(v.minor, 2);
75 assert_eq!(v.patch, 3);
76 }
77
78 #[test]
79 fn test_semantic_version_parsing_invalid() {
80 assert!(SemanticVersion::parse("1.2").is_err());
81 assert!(SemanticVersion::parse("1.2.3.4").is_err());
82 assert!(SemanticVersion::parse("a.b.c").is_err());
83 }
84
85 #[test]
86 fn test_version_comparison() {
87 let v1 = SemanticVersion::new(1, 0, 0);
88 let v2 = SemanticVersion::new(2, 0, 0);
89 assert!(v1 < v2);
90
91 let v3 = SemanticVersion::new(1, 2, 0);
92 let v4 = SemanticVersion::new(1, 1, 0);
93 assert!(v3 > v4);
94
95 let v5 = SemanticVersion::new(1, 1, 2);
96 let v6 = SemanticVersion::new(1, 1, 1);
97 assert!(v5 > v6);
98 }
99
100 #[test]
101 fn test_version_bump_major() {
102 let mut v = SemanticVersion::new(1, 2, 3);
103 v.bump_major();
104 assert_eq!(v, SemanticVersion::new(2, 0, 0));
105 }
106
107 #[test]
108 fn test_version_bump_minor() {
109 let mut v = SemanticVersion::new(1, 2, 3);
110 v.bump_minor();
111 assert_eq!(v, SemanticVersion::new(1, 3, 0));
112 }
113
114 #[test]
115 fn test_version_bump_patch() {
116 let mut v = SemanticVersion::new(1, 2, 3);
117 v.bump_patch();
118 assert_eq!(v, SemanticVersion::new(1, 2, 4));
119 }
120
121 #[test]
122 fn test_version_display() {
123 let v = SemanticVersion::new(1, 2, 3);
124 assert_eq!(format!("{}", v), "1.2.3");
125 }
126
127 #[test]
128 fn test_version_default() {
129 let v = SemanticVersion::default();
130 assert_eq!(v, SemanticVersion::new(1, 0, 0));
131 }
132
133 #[test]
134 fn test_version_serialization() {
135 let v = SemanticVersion::new(1, 2, 3);
136 let json = serde_json::to_string(&v).unwrap();
137 let deserialized: SemanticVersion = serde_json::from_str(&json).unwrap();
138 assert_eq!(v, deserialized);
139 }
140}