Skip to main content

bity_ic_types/
build_version.rs

1//! Provides version management utilities for Internet Computer canisters.
2//!
3//! This module implements a semantic versioning system through the `BuildVersion` struct,
4//! following the MAJOR.MINOR.PATCH format.
5
6use candid::CandidType;
7use serde::{Deserialize, Serialize};
8use std::fmt::{Display, Formatter};
9use std::str::FromStr;
10
11/// Represents a semantic version number following the MAJOR.MINOR.PATCH format.
12///
13/// # Examples
14///
15/// ```
16/// use types::BuildVersion;
17///
18/// let version = BuildVersion::new(1, 2, 3);
19/// assert_eq!(version.to_string(), "1.2.3");
20///
21/// let parsed = "1.2.3".parse::<BuildVersion>().unwrap();
22/// assert_eq!(version, parsed);
23/// ```
24#[derive(
25    CandidType, Serialize, Deserialize, Clone, Copy, Debug, Default, Ord, PartialOrd, Eq, PartialEq,
26)]
27pub struct BuildVersion {
28    /// Major version number, incremented for incompatible API changes
29    pub major: u32,
30    /// Minor version number, incremented for backwards-compatible functionality additions
31    pub minor: u32,
32    /// Patch version number, incremented for backwards-compatible bug fixes
33    pub patch: u32,
34}
35
36impl BuildVersion {
37    /// Creates a new BuildVersion with the specified version numbers.
38    ///
39    /// # Arguments
40    ///
41    /// * `major` - The major version number
42    /// * `minor` - The minor version number
43    /// * `patch` - The patch version number
44    pub fn new(major: u32, minor: u32, patch: u32) -> BuildVersion {
45        BuildVersion {
46            major,
47            minor,
48            patch,
49        }
50    }
51
52    /// Returns the minimum possible version (0.0.0).
53    pub fn min() -> BuildVersion {
54        BuildVersion::default()
55    }
56}
57
58impl Display for BuildVersion {
59    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60        f.write_str(&format!("{}.{}.{}", self.major, self.minor, self.patch))
61    }
62}
63
64impl FromStr for BuildVersion {
65    type Err = String;
66
67    fn from_str(s: &str) -> Result<Self, Self::Err> {
68        let parts: Vec<_> = s.split('.').collect();
69        if parts.len() != 3 {
70            return Err(format!("Unable to parse version: {s}"));
71        }
72
73        let major = u32::from_str(parts[0]).map_err(|e| e.to_string())?;
74        let minor = u32::from_str(parts[1]).map_err(|e| e.to_string())?;
75        let patch = u32::from_str(parts[2]).map_err(|e| e.to_string())?;
76
77        Ok(BuildVersion {
78            major,
79            minor,
80            patch,
81        })
82    }
83}