utils 0.0.3

Common utilities suitable for use in Rust Builders
#![allow(unstable)]
extern crate commandext;

use commandext::{CommandExt,to_procout};
use std::cmp::{max,min};
use std::str;
#[cfg(windows)]
use std::os;

pub mod empty;

/// The number of available cpu cores.
#[experimental]
pub fn nproc() -> u8 {
    match CommandExt::new("nproc").exec(to_procout()) {
        Ok(p) => {
            match str::from_utf8(p.output.as_slice()).unwrap().trim().parse() {
                Some(i) => i,
                None    => panic!("unable to cast nproc output!"),
            }
        },
        Err(e) => panic!("Failed to execute nproc: {}", e),
    }
}

/// The number of usable cores `min(4, max(1, (nproc - 1)))`.
///
/// This returns a number between 1 and 4.
#[experimental]
pub fn usable_cores() -> u8 {
    let usable = nproc() - 1;
    min(4, max(1, usable))
}

/// The machine hardware value as given by "uname -m"
#[cfg(unix)]
#[experimental]
pub fn mh() -> String {
    match CommandExt::new("uname").arg("-m").exec(to_procout()) {
        Ok(o)  => {
            let mut res =  String::from_utf8_lossy(o.output.as_slice());
            res.to_mut().trim().to_string()
        },
        Err(e) => panic!("Failed to execute uname: {}", e),
    }
}

/// The machine hardware value as given in the PROCESSOR_ARCHITECTURE and
/// PROCESSOR_ARCHITEW6432 environment variables.
#[cfg(windows)]
#[experimental]
pub fn mh() -> String {
    let pa = "PROCESSOR_ARCHITECTURE";
    let val = match os::getenv(pa) {
        Some(v) => v,
        None    => "".to_string(),
    };

    if !(val == "AMD64") {
        let paw = "PROCESSOR_ARCHITEW6432";
        let val1 = match os::getenv(paw) {
            Some(v) => v,
            None => "".to_string(),
        };

        if val1 == "AMD64" {
            val1
        } else {
            "x86".to_string()
        }
    } else {
        val
    }
}

/// Is the current machine hardware 64-bit?
#[experimental]
pub fn is_64() -> bool {
    cfg!(target_pointer_width = "64")
}

/// Is the current machine hardware 32-bit?
#[experimental]
pub fn is_32() -> bool {
   cfg!(target_pointer_width = "32")
}

#[cfg(test)]
/// Tests
mod test {
    use super::{is_32,is_64,mh,nproc,usable_cores};

    #[test]
    fn test_nproc() {
        assert!(nproc() > 0);
    }

    #[test]
    fn test_usable_cores() {
        assert!(0 < usable_cores());
        assert!(4 >= usable_cores());
    }

    #[test]
    #[cfg(all (unix, target_arch = "x86_64"))]
    fn test_mh() {
        assert_eq!(mh(), "x86_64");
    }

    #[test]
    #[cfg(all (windows, target_arch = "x86_64"))]
    fn test_mh() {
        assert_eq!(mh(), "AMD64");
    }

    #[test]
    #[cfg(all (unix, target_arch = "x86"))]
    fn test_mh() {
        assert_eq!(mh(), "i686");
    }

    #[test]
    #[cfg(all (windows, target_arch = "x86"))]
    fn test_mh() {
        assert_eq!(mh(), "x86");
    }

    #[test]
    #[cfg(target_arch = "x86_64")]
    fn test_is_64() {
        assert!(is_64());
        assert!(!is_32());
    }

    #[test]
    #[cfg(target_arch = "x86")]
    fn test_is_32() {
        assert!(is_32());
        assert!(!is_64());
    }
}