1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#[cfg(test)]
#[path = "./rustinfo_test.rs"]
mod rustinfo_test;
use crate::types::{RustChannel, RustInfo};
use std::collections::HashMap;
use std::io::Error;
use std::process::{Command, ExitStatus};
fn get_exit_code(exit_status: Result<ExitStatus, Error>) -> i32 {
match exit_status {
Ok(code) => {
if !code.success() {
match code.code() {
Some(value) => value,
None => -1,
}
} else {
0
}
}
_ => -1,
}
}
fn load_version(rust_info: &mut RustInfo) {
let result = Command::new("rustc").arg("--version").output();
match result {
Ok(output) => {
let exit_code = get_exit_code(Ok(output.status));
if exit_code == 0 {
let stdout = String::from_utf8_lossy(&output.stdout);
let parts: Vec<&str> = stdout.split(' ').collect();
if (parts.len() >= 3) && (parts[0] == "rustc") {
let version_part = parts[1];
let version_parts: Vec<&str> = version_part.split('-').collect();
if version_parts.len() > 0 {
rust_info.version = Some(version_parts[0].to_string());
if version_parts.len() == 1 {
rust_info.channel = Some(RustChannel::Stable);
} else if version_parts[1].contains("beta") {
rust_info.channel = Some(RustChannel::Beta);
} else if version_parts[1].contains("nightly") {
rust_info.channel = Some(RustChannel::Nightly);
}
}
}
}
}
_ => (),
};
}
fn load_setup(rust_info: &mut RustInfo) {
let result = Command::new("rustc").arg("--print").arg("cfg").output();
match result {
Ok(output) => {
let exit_code = get_exit_code(Ok(output.status));
if exit_code == 0 {
let mut values = HashMap::<String, String>::new();
let stdout = String::from_utf8_lossy(&output.stdout);
let lines: Vec<&str> = stdout.split('\n').collect();
for mut line in lines {
line = line.trim();
if line.contains("=") {
let parts: Vec<&str> = line.split('=').collect();
let value = str::replace(parts[1], "\"", "");
values.insert(parts[0].to_string(), value.to_string());
}
}
let mut value = values.remove("target_arch");
if value.is_some() {
rust_info.target_arch = Some(value.unwrap());
}
value = values.remove("target_env");
if value.is_some() {
rust_info.target_env = Some(value.unwrap());
}
value = values.remove("target_os");
if value.is_some() {
rust_info.target_os = Some(value.unwrap());
}
value = values.remove("target_pointer_width");
if value.is_some() {
rust_info.target_pointer_width = Some(value.unwrap());
}
value = values.remove("target_vendor");
if value.is_some() {
rust_info.target_vendor = Some(value.unwrap());
}
}
}
_ => (),
};
}
pub(crate) fn get() -> RustInfo {
let mut rust_info = RustInfo::new();
load_version(&mut rust_info);
load_setup(&mut rust_info);
rust_info
}