Skip to main content

ai_agent/utils/
semver.rs

1// Source: /data/home/swei/claudecode/openclaudecode/src/utils/semver.ts
2//! Semantic version utilities.
3
4use std::cmp::Ordering;
5
6/// Parse a semantic version string
7pub fn parse_semver(version: &str) -> Option<Semver> {
8    let version = version.trim();
9
10    // Remove 'v' prefix if present
11    let version = version.strip_prefix('v').unwrap_or(version);
12
13    let parts: Vec<&str> = version.split('.').collect();
14
15    if parts.is_empty() {
16        return None;
17    }
18
19    let major = parts[0].parse().ok()?;
20    let minor = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
21    let patch = parts
22        .get(2)
23        .and_then(|s| s.split('-').next()?.parse().ok())
24        .unwrap_or(0);
25
26    Some(Semver {
27        major,
28        minor,
29        patch,
30    })
31}
32
33/// A semantic version
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub struct Semver {
36    pub major: u32,
37    pub minor: u32,
38    pub patch: u32,
39}
40
41impl Semver {
42    pub fn new(major: u32, minor: u32, patch: u32) -> Self {
43        Self {
44            major,
45            minor,
46            patch,
47        }
48    }
49
50    /// Compare two semantic versions
51    pub fn compare(&self, other: &Semver) -> Ordering {
52        self.major
53            .cmp(&other.major)
54            .then(self.minor.cmp(&other.minor))
55            .then(self.patch.cmp(&other.patch))
56    }
57
58    /// Check if this version is compatible with another (same major version)
59    pub fn is_compatible(&self, other: &Semver) -> bool {
60        self.major == other.major
61    }
62
63    /// Check if this version is greater than another
64    pub fn gt(&self, other: &Semver) -> bool {
65        self.compare(other) == Ordering::Greater
66    }
67
68    /// Check if this version is less than another
69    pub fn lt(&self, other: &Semver) -> bool {
70        self.compare(other) == Ordering::Less
71    }
72
73    /// Check if this version is equal to another
74    pub fn eq(&self, other: &Semver) -> bool {
75        self.compare(other) == Ordering::Equal
76    }
77}
78
79impl std::fmt::Display for Semver {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
82    }
83}
84
85impl PartialOrd for Semver {
86    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
87        Some(self.compare(other))
88    }
89}
90
91impl Ord for Semver {
92    fn cmp(&self, other: &Self) -> Ordering {
93        self.compare(other)
94    }
95}