Skip to main content

conmonrs/
version.rs

1//! Generic version information for conmon
2
3use anyhow::{Context, Result};
4use serde::Serialize;
5
6/// The version structure.
7#[derive(Debug, Default, Eq, PartialEq, Serialize)]
8pub struct Version {
9    /// Specifies if the output should contain verbose debug information.
10    verbose: bool,
11
12    /// The current crate version.
13    version: &'static str,
14
15    /// The tag of the build, empty if not available.
16    tag: &'static str,
17
18    /// The git commit SHA of the build.
19    commit: &'static str,
20
21    /// The build date string.
22    build_date: &'static str,
23
24    /// The target triple string.
25    target: &'static str,
26
27    /// The used Rust version.
28    rust_version: &'static str,
29
30    /// The used Cargo version.
31    cargo_version: &'static str,
32
33    /// The cargo dependency tree, only available in verbose output.
34    cargo_tree: &'static str,
35}
36
37impl Version {
38    /// Create a new Version instance.
39    pub fn new(verbose: bool) -> Self {
40        Self {
41            verbose,
42            version: env!("CARGO_PKG_VERSION"),
43            tag: env!("BUILD_TAG"),
44            commit: env!("BUILD_COMMIT"),
45            build_date: env!("BUILD_TIME"),
46            target: env!("BUILD_TARGET"),
47            rust_version: env!("BUILD_RUST_VERSION"),
48            cargo_version: env!("BUILD_CARGO_VERSION"),
49            cargo_tree: if verbose {
50                env!("BUILD_CARGO_TREE")
51            } else {
52                ""
53            },
54        }
55    }
56
57    /// Whether verbose output is enabled.
58    pub fn verbose(&self) -> bool {
59        self.verbose
60    }
61
62    /// The current crate version.
63    pub fn version(&self) -> &'static str {
64        self.version
65    }
66
67    /// The tag of the build.
68    pub fn tag(&self) -> &'static str {
69        self.tag
70    }
71
72    /// The git commit SHA.
73    pub fn commit(&self) -> &'static str {
74        self.commit
75    }
76
77    /// The build date string.
78    pub fn build_date(&self) -> &'static str {
79        self.build_date
80    }
81
82    /// The target triple.
83    pub fn target(&self) -> &'static str {
84        self.target
85    }
86
87    /// The Rust version used.
88    pub fn rust_version(&self) -> &'static str {
89        self.rust_version
90    }
91
92    /// The Cargo version used.
93    pub fn cargo_version(&self) -> &'static str {
94        self.cargo_version
95    }
96
97    /// The cargo dependency tree.
98    pub fn cargo_tree(&self) -> &'static str {
99        self.cargo_tree
100    }
101
102    /// Print the version information to stdout.
103    pub fn print(&self) {
104        println!("version: {}", self.version());
105        println!(
106            "tag: {}",
107            if self.tag().is_empty() {
108                "none"
109            } else {
110                self.tag()
111            }
112        );
113        println!("commit: {}", self.commit());
114        println!("build: {}", self.build_date());
115        println!("target: {}", self.target());
116        println!("{}", self.rust_version());
117        println!("{}", self.cargo_version());
118
119        if self.verbose() {
120            println!("\ncargo tree: {}", self.cargo_tree());
121        }
122    }
123
124    /// Print the version information as JSON to stdout.
125    pub fn print_json(&self) -> Result<()> {
126        println!(
127            "{}",
128            serde_json::to_string(&self).context("serialize result")?
129        );
130        Ok(())
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn version_test() {
140        let v = Version::new(false);
141        assert_eq!(v.version(), env!("CARGO_PKG_VERSION"));
142        assert_eq!(v.tag(), env!("BUILD_TAG"));
143        assert_eq!(v.commit(), env!("BUILD_COMMIT"));
144        assert_eq!(v.build_date(), env!("BUILD_TIME"));
145        assert_eq!(v.target(), env!("BUILD_TARGET"));
146        assert_eq!(v.rust_version(), env!("BUILD_RUST_VERSION"));
147        assert_eq!(v.cargo_version(), env!("BUILD_CARGO_VERSION"));
148        assert!(v.cargo_tree().is_empty());
149
150        v.print();
151    }
152
153    #[test]
154    fn version_test_verbose() {
155        let v = Version::new(true);
156        assert_eq!(v.cargo_tree(), env!("BUILD_CARGO_TREE"));
157    }
158
159    #[test]
160    fn version_test_json() -> Result<()> {
161        let v = Version::new(false);
162        assert_eq!(v.version(), env!("CARGO_PKG_VERSION"));
163        assert_eq!(v.tag(), env!("BUILD_TAG"));
164        assert_eq!(v.commit(), env!("BUILD_COMMIT"));
165        assert_eq!(v.build_date(), env!("BUILD_TIME"));
166        assert_eq!(v.target(), env!("BUILD_TARGET"));
167        assert_eq!(v.rust_version(), env!("BUILD_RUST_VERSION"));
168        assert_eq!(v.cargo_version(), env!("BUILD_CARGO_VERSION"));
169        assert!(v.cargo_tree().is_empty());
170
171        v.print_json()?;
172        Ok(())
173    }
174}