assemble_core/
version.rs

1//! Provide version information about assemble, generated at compile time.
2
3use semver::VersionReq;
4use std::cmp::Ordering;
5use std::fmt::{Display, Formatter};
6
7/// Version information about this version of assemble
8#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
9pub struct Version {
10    name: String,
11    version: String,
12}
13
14impl Version {
15    /// Get an instance of the version
16    fn instance() -> Self {
17        let name = env!("CARGO_PKG_NAME");
18        let version = env!("CARGO_PKG_VERSION");
19        Self {
20            name: name.to_string(),
21            version: version.to_string(),
22        }
23    }
24
25    /// Creates a new version instance with an arbitrary version and build
26    pub fn new(build: &str, version: &str) -> Self {
27        Self {
28            name: build.to_string(),
29            version: version.to_string(),
30        }
31    }
32
33    /// Creates a new version instance with an arbitrary version, but for the `assemble-core` build
34    pub fn with_version(version: &str) -> Self {
35        Self::new(env!("CARGO_PKG_NAME"), version)
36    }
37
38    /// Get the name of the package. Should always return `assemble-core`
39    pub fn name(&self) -> &str {
40        &self.name
41    }
42
43    /// Get the version of the package.
44    pub fn version(&self) -> &str {
45        &self.version
46    }
47
48    /// Check if this version matches some version requirement as expressed in Semver terms
49    pub fn match_requirement(&self, req: &str) -> bool {
50        let req = VersionReq::parse(req)
51            .unwrap_or_else(|_| panic!("Invalid requirement string: {req:?}"));
52        let semver = semver::Version::parse(&self.version)
53            .unwrap_or_else(|_| panic!("Invalid version string: {:?}", self.version));
54        req.matches(&semver)
55    }
56}
57
58impl Display for Version {
59    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60        write!(f, "v{}", self.version)
61    }
62}
63
64/// Get version information about assemble
65pub fn version() -> Version {
66    Version::instance()
67}
68
69impl PartialOrd for Version {
70    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
71        if self.name != other.name {
72            return None;
73        }
74
75        let this_version = semver::Version::parse(&self.version).ok()?;
76        let other_version = semver::Version::parse(&other.version).ok()?;
77        this_version.partial_cmp(&other_version)
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn get_version_info() {
87        let version = version();
88        assert_eq!(version.name(), "assemble-core");
89        let semver = semver::Version::parse(version.version()).unwrap();
90        let added = semver::Version::new(0, 1, 2);
91        assert!(semver >= added);
92    }
93}