1pub const VERSION: &str = env!("CARGO_PKG_VERSION");
11
12pub const GIT_HASH: &str = env!("GIT_HASH");
14
15pub const BUILD_TIME: &str = env!("BUILD_TIME");
17
18pub const RUST_VERSION: &str = env!("RUST_VERSION");
20
21pub fn full_version() -> String {
23 format!("{}-{}", VERSION, GIT_HASH)
24}
25
26pub fn build_info() -> BuildInfo {
28 BuildInfo {
29 version: VERSION,
30 git_hash: GIT_HASH,
31 build_time: BUILD_TIME,
32 rust_version: RUST_VERSION,
33 }
34}
35
36#[derive(Debug, Clone, serde::Serialize)]
38pub struct BuildInfo {
39 pub version: &'static str,
40 pub git_hash: &'static str,
41 pub build_time: &'static str,
42 pub rust_version: &'static str,
43}
44
45impl std::fmt::Display for BuildInfo {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(
48 f,
49 "{}-{} (built {} with {})",
50 self.version, self.git_hash, self.build_time, self.rust_version
51 )
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_version_not_empty() {
61 assert!(!VERSION.is_empty());
62 }
63
64 #[test]
65 fn test_git_hash_not_empty() {
66 assert!(!GIT_HASH.is_empty());
67 }
68
69 #[test]
70 fn test_full_version_format() {
71 let full = full_version();
72 assert!(full.contains('-'));
73 assert!(full.starts_with(VERSION));
74 }
75
76 #[test]
77 fn test_build_info_serializable() {
78 let info = build_info();
79 let json = serde_json::to_string(&info).unwrap();
80 assert!(json.contains("version"));
81 assert!(json.contains("git_hash"));
82 }
83}