#![doc(html_root_url = "https://docs.rs/feature-probe/0.1.1")]
use std::env;
use std::ffi::OsString;
use std::io::{self, Write};
use std::process::{Command, Stdio};
#[derive(Debug)]
pub struct Probe {
rustc: OsString,
out_dir: OsString,
}
impl Probe {
pub fn new() -> Self {
Probe {
rustc: env_var_or("RUSTC", "rustc"),
out_dir: env_var_or("OUT_DIR", "target"),
}
}
pub fn probe_type(&self, type_name: &str) -> bool {
self.probe(&format!("pub type T = {}; fn main() {{ }}", type_name))
}
pub fn probe_expression(&self, expression: &str) -> bool {
self.probe(&format!("fn main() {{ {}; }}", expression))
}
pub fn probe(&self, code: &str) -> bool {
self.probe_result(code).expect("Probe::probe")
}
pub fn probe_result(&self, code: &str) -> io::Result<bool> {
let mut child = Command::new(&self.rustc)
.arg("--out-dir")
.arg(&self.out_dir)
.arg("--emit=obj")
.arg("-")
.stdin(Stdio::piped())
.spawn()?;
child
.stdin
.as_mut().unwrap()
.write_all(code.as_bytes())?;
Ok(child.wait()?.success())
}
}
impl Default for Probe {
fn default() -> Self {
Probe::new()
}
}
fn env_var_or(var: &str, default: &str) -> OsString {
env::var_os(var).unwrap_or_else(|| default.into())
}