Skip to main content

semver_common/models/
version.rs

1use crate::CommitMap;
2use derive_getters::Getters;
3use serde::{Deserialize, Serialize};
4
5/// Data structure that contains a version with a major, minor, and patch number as well as a map
6/// of commits that represent changes since the previous version.
7#[derive(Serialize, Deserialize, Getters)]
8pub struct Version {
9    major: u32,
10    minor: u32,
11    patch: u32,
12    changes: CommitMap,
13}
14
15impl Default for Version {
16    fn default() -> Self {
17        Self::new(0, 0, 0, CommitMap::new())
18    }
19}
20
21impl Version {
22    /// Gets the version in string form. Formatted, "v(major).(minor).(patch)"
23    pub fn get(&self) -> String {
24        format!("v{}.{}.{}", self.major, self.minor, self.patch)
25    }
26
27    /// Parse a string into the appropriate version numbers. Returns a tuple containing
28    /// the major, minor, and patch version numbers extracted from the string, if available.
29    pub fn parse(version: &str) -> Option<(u32, u32, u32)> {
30        if version.len() <= 1 {
31            return None;
32        }
33        let separated: Vec<&str> = version[1..].split(".").collect();
34        if separated.len() == 3 {
35            let major_version = separated.first()?;
36            let minor_version = separated.get(1)?;
37            let patch_version = separated.get(2)?;
38            return Some((
39                major_version.parse().ok()?,
40                minor_version.parse().ok()?,
41                patch_version.parse().ok()?,
42            ));
43        }
44        None
45    }
46
47    pub fn new(major: u32, minor: u32, patch: u32, changes: CommitMap) -> Self {
48        Version {
49            major,
50            minor,
51            patch,
52            changes,
53        }
54    }
55}
56
57#[cfg(test)]
58mod test {
59    use super::*;
60
61    #[test]
62    fn test_version_parse_valid() {
63        let parse_value = Version::parse("v1.9.2");
64        assert_eq!(parse_value, Some((1, 9, 2)));
65    }
66
67    #[test]
68    fn test_version_parse_invalid_full_len() {
69        let parse_value = Version::parse("oopasdf91.9.2ff");
70        assert_eq!(parse_value, None);
71    }
72
73    #[test]
74    fn test_version_parse_invalid_one_len() {
75        let parse_value = Version::parse("v");
76        assert_eq!(parse_value, None);
77    }
78
79    #[test]
80    fn test_version_parse_invalid_no_input() {
81        let parse_value = Version::parse("");
82        assert_eq!(parse_value, None);
83    }
84
85    #[test]
86    fn test_version_parse_invalid_no_int() {
87        let parse_value = Version::parse("vIU.AB.PE");
88        assert_eq!(parse_value, None);
89    }
90
91    #[test]
92    fn test_version_get() {
93        let (major, minor, patch) = Version::parse("v1.9.2").unwrap();
94        let changes = CommitMap::new();
95        let version = Version::new(major, minor, patch, changes);
96        assert_eq!(version.get(), "v1.9.2");
97    }
98}