1use anyhow::{Context, Result};
4use serde::Serialize;
5
6#[derive(Debug, Default, Eq, PartialEq, Serialize)]
8pub struct Version {
9 verbose: bool,
11
12 version: &'static str,
14
15 tag: &'static str,
17
18 commit: &'static str,
20
21 build_date: &'static str,
23
24 target: &'static str,
26
27 rust_version: &'static str,
29
30 cargo_version: &'static str,
32
33 cargo_tree: &'static str,
35}
36
37impl Version {
38 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 pub fn verbose(&self) -> bool {
59 self.verbose
60 }
61
62 pub fn version(&self) -> &'static str {
64 self.version
65 }
66
67 pub fn tag(&self) -> &'static str {
69 self.tag
70 }
71
72 pub fn commit(&self) -> &'static str {
74 self.commit
75 }
76
77 pub fn build_date(&self) -> &'static str {
79 self.build_date
80 }
81
82 pub fn target(&self) -> &'static str {
84 self.target
85 }
86
87 pub fn rust_version(&self) -> &'static str {
89 self.rust_version
90 }
91
92 pub fn cargo_version(&self) -> &'static str {
94 self.cargo_version
95 }
96
97 pub fn cargo_tree(&self) -> &'static str {
99 self.cargo_tree
100 }
101
102 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 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}