conmonrs/
version.rs

1//! Generic version information for conmon
2
3#![allow(clippy::uninlined_format_args)]
4#![allow(clippy::needless_raw_string_hashes)]
5
6use anyhow::{Context, Result};
7use getset::CopyGetters;
8use serde::Serialize;
9use shadow_rs::shadow;
10
11shadow!(build);
12
13#[derive(CopyGetters, Debug, Default, Eq, PartialEq, Serialize)]
14#[getset(get_copy = "pub")]
15/// The version structure.
16pub struct Version {
17    /// Specifies if the output should contain verbose debug information.
18    verbose: bool,
19
20    /// The current crate version.
21    version: &'static str,
22
23    /// The tag of the build, empty if not available.
24    tag: &'static str,
25
26    /// The git commit SHA of the build.
27    commit: &'static str,
28
29    /// The build date string.
30    build_date: &'static str,
31
32    /// The target triple string.
33    target: &'static str,
34
35    /// The used Rust version.
36    rust_version: &'static str,
37
38    /// The used Cargo version.
39    cargo_version: &'static str,
40
41    /// The cargo dependency tree, only available in verbose output.
42    cargo_tree: &'static str,
43}
44
45impl Version {
46    /// Create a new Version instance.
47    pub fn new(verbose: bool) -> Self {
48        Self {
49            verbose,
50            version: build::PKG_VERSION,
51            tag: build::TAG,
52            commit: build::COMMIT_HASH,
53            build_date: build::BUILD_TIME,
54            target: build::BUILD_TARGET,
55            rust_version: build::RUST_VERSION,
56            cargo_version: build::CARGO_VERSION,
57            cargo_tree: if verbose { build::CARGO_TREE } else { "" },
58        }
59    }
60
61    /// Print the version information to stdout.
62    pub fn print(&self) {
63        println!("version: {}", self.version());
64        println!(
65            "tag: {}",
66            if self.tag().is_empty() {
67                "none"
68            } else {
69                self.tag()
70            }
71        );
72        println!("commit: {}", self.commit());
73        println!("build: {}", self.build_date());
74        println!("target: {}", self.target());
75        println!("{}", self.rust_version());
76        println!("{}", self.cargo_version());
77
78        if self.verbose() {
79            println!("\ncargo tree: {}", self.cargo_tree());
80        }
81    }
82
83    /// Print the version information as JSON to stdout.
84    pub fn print_json(&self) -> Result<()> {
85        println!(
86            "{}",
87            serde_json::to_string(&self).context("serialize result")?
88        );
89        Ok(())
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn version_test() {
99        let v = Version::new(false);
100        assert_eq!(v.version(), build::PKG_VERSION);
101        assert_eq!(v.tag(), build::TAG);
102        assert_eq!(v.commit(), build::COMMIT_HASH);
103        assert_eq!(v.build_date(), build::BUILD_TIME);
104        assert_eq!(v.target(), build::BUILD_TARGET);
105        assert_eq!(v.rust_version(), build::RUST_VERSION);
106        assert_eq!(v.cargo_version(), build::CARGO_VERSION);
107        assert!(v.cargo_tree().is_empty());
108
109        v.print();
110    }
111
112    #[test]
113    fn version_test_verbose() {
114        let v = Version::new(true);
115        assert_eq!(v.cargo_tree(), build::CARGO_TREE);
116    }
117
118    #[test]
119    fn version_test_json() -> Result<()> {
120        let v = Version::new(false);
121        assert_eq!(v.version(), build::PKG_VERSION);
122        assert_eq!(v.tag(), build::TAG);
123        assert_eq!(v.commit(), build::COMMIT_HASH);
124        assert_eq!(v.build_date(), build::BUILD_TIME);
125        assert_eq!(v.target(), build::BUILD_TARGET);
126        assert_eq!(v.rust_version(), build::RUST_VERSION);
127        assert_eq!(v.cargo_version(), build::CARGO_VERSION);
128        assert!(v.cargo_tree().is_empty());
129
130        v.print_json()?;
131        Ok(())
132    }
133}