1 use std::env;
2 use std::ffi::OsString;
3 use std::io::{self, Write};
4 use std::process::Command;
5
main()6 fn main() {
7 let version = match Version::read() {
8 Ok(version) => version,
9 Err(err) => {
10 writeln!(
11 &mut io::stderr(),
12 "failed to parse `rustc --version`: {}",
13 err
14 ).unwrap();
15 return;
16 }
17 };
18 enable_i128(version);
19 }
20
enable_i128(version: Version)21 fn enable_i128(version: Version) {
22 if version < (Version { major: 1, minor: 26, patch: 0 }) {
23 return;
24 }
25
26 println!("cargo:rustc-cfg=byteorder_i128");
27 }
28
29 #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
30 struct Version {
31 major: u32,
32 minor: u32,
33 patch: u32,
34 }
35
36 impl Version {
read() -> Result<Version, String>37 fn read() -> Result<Version, String> {
38 let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc"));
39 let output = Command::new(&rustc)
40 .arg("--version")
41 .output()
42 .unwrap()
43 .stdout;
44 Version::parse(&String::from_utf8(output).unwrap())
45 }
46
parse(mut s: &str) -> Result<Version, String>47 fn parse(mut s: &str) -> Result<Version, String> {
48 if !s.starts_with("rustc ") {
49 return Err(format!("unrecognized version string: {}", s));
50 }
51 s = &s["rustc ".len()..];
52
53 let parts: Vec<&str> = s.split(".").collect();
54 if parts.len() < 3 {
55 return Err(format!("not enough version parts: {:?}", parts));
56 }
57
58 let mut num = String::new();
59 for c in parts[0].chars() {
60 if !c.is_digit(10) {
61 break;
62 }
63 num.push(c);
64 }
65 let major = try!(num.parse::<u32>().map_err(|e| e.to_string()));
66
67 num.clear();
68 for c in parts[1].chars() {
69 if !c.is_digit(10) {
70 break;
71 }
72 num.push(c);
73 }
74 let minor = try!(num.parse::<u32>().map_err(|e| e.to_string()));
75
76 num.clear();
77 for c in parts[2].chars() {
78 if !c.is_digit(10) {
79 break;
80 }
81 num.push(c);
82 }
83 let patch = try!(num.parse::<u32>().map_err(|e| e.to_string()));
84
85 Ok(Version { major: major, minor: minor, patch: patch })
86 }
87 }
88