rust_tools_version/
lib.rs1use std::fmt;
2use std::process::Command;
3
4pub const CURRENT_STABLE: Version = Version {
5 major: 1,
6 minor: 20,
7 patch: 0,
8};
9
10pub const CURRENT_BETA: Version = Version {
11 major: 1,
12 minor: 21,
13 patch: 0,
14};
15
16pub const CURRENT_NIGHTLY: Version = Version {
17 major: 1,
18 minor: 22,
19 patch: 0,
20};
21
22#[derive(Debug, Copy, Clone, Eq, PartialEq)]
23pub struct Version {
24 pub major: u32,
25 pub minor: u32,
26 pub patch: u32,
27}
28
29impl fmt::Display for Version {
30 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
31 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
32 }
33}
34
35impl Version {
36 pub fn new(major: u32, minor: u32, patch: u32) -> Version {
37 Version {
38 major,
39 minor,
40 patch,
41 }
42 }
43
44 pub fn from_env_var() -> Option<Version> {
45 option_env!("CFG_VERSION").and_then(|s| Self::from_string(&s))
46 }
47
48 fn from_string(version_str: &str) -> Option<Version> {
49 use std::str::FromStr;
50 macro_rules! try_opt {
51 ($x: expr) => {
52 match $x {
53 Some(Ok(x)) => x,
54 _ => return None,
55 }
56 }
57 }
58
59 let mut nums = version_str.split('.').map(u32::from_str);
60 Some(Version::new(try_opt!(nums.next()), try_opt!(nums.next()), try_opt!(nums.next())))
61 }
62
63 pub fn to_unstable_tool_string(&self) -> String {
64 format!("0.{}{}.{}", self.major, self.minor, self.patch)
65 }
66
67 pub fn to_stable_tool_string(&self) -> String {
68 format!("{}{}.{}.0", self.major, self.minor, self.patch)
69 }
70}
71
72
73pub fn channel() -> Option<&'static str> {
74 option_env!("CFG_RELEASE_CHANNEL")
75}
76
77pub fn commit_hash() -> Option<String> {
78 Command::new("git")
79 .args(&["rev-parse", "--short", "HEAD"])
80 .output()
81 .ok()
82 .and_then(|r| String::from_utf8(r.stdout).ok())
83}
84
85pub fn commit_date() -> Option<String> {
86 Command::new("git")
87 .args(&["log",
88 "-1",
89 "--date=short",
90 "--pretty=format:%cd"])
91 .output()
92 .ok()
93 .and_then(|r| String::from_utf8(r.stdout).ok())
94}
95
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_formatting() {
103 let v = Version::new(1, 2, 3);
104 assert_eq!(&v.to_string(), "1.2.3");
105 assert_eq!(&v.to_unstable_tool_string(), "0.12.3");
106 assert_eq!(&v.to_stable_tool_string(), "12.3.0");
107 }
108
109 #[test]
110 fn test_from_str() {
111 assert_eq!(Version::from_string("0.0"), None);
112 assert_eq!(Version::from_string("0.0.a"), None);
113 assert_eq!(Version::from_string("0.."), None);
114 assert_eq!(Version::from_string("0.0.0"), Some(Version::new(0, 0, 0)));
115 assert_eq!(Version::from_string("3.2.1"), Some(Version::new(3, 2, 1)));
116 }
117}