use crate::{
retrieve::cache::Cache,
util::{config::Backend, errors::Res, fmt_output},
};
use failure::{format_err, ResultExt};
use std::{
path::{Path, PathBuf},
process::Command,
};
#[derive(Debug)]
pub struct BuildContext<'a> {
pub backend: &'a Backend,
pub codegen: bool,
pub compiler: Compiler,
pub cache: &'a Cache,
pub threads: u32,
pub opts: &'a [String],
}
#[derive(Debug)]
pub struct Compiler {
path: PathBuf,
flavor: CompilerFlavor,
}
impl Compiler {
pub fn new(name: &str) -> Res<Compiler> {
let c = Compiler {
path: PathBuf::from(name),
flavor: CompilerFlavor::Idris1,
};
let flavor = if c.version()?.starts_with("Blodwen") {
CompilerFlavor::Idris2
} else {
CompilerFlavor::Idris1
};
Ok(Compiler { flavor, ..c })
}
pub fn process(&self) -> Command {
Command::new(&self.path)
}
pub fn path(&self) -> &Path {
&self.path
}
pub fn flavor(&self) -> CompilerFlavor {
self.flavor
}
pub fn version(&self) -> Res<String> {
let out = Command::new(&self.path)
.arg("--version")
.output()
.with_context(|e| format!("couldn't retrieve Idris compiler version: {}", e))?;
if out.status.success() {
Ok(String::from_utf8_lossy(&out.stdout).trim().to_string())
} else {
Err(format_err!(
"couldn't get idris version:\n{}",
fmt_output(&out)
))
}
}
}
impl Default for Compiler {
fn default() -> Self {
Compiler {
path: PathBuf::from("idris"),
flavor: CompilerFlavor::Idris1,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CompilerFlavor {
Idris1,
Idris2,
}
impl CompilerFlavor {
pub fn is_idris1(self) -> bool {
match self {
CompilerFlavor::Idris1 => true,
_ => false,
}
}
pub fn is_idris2(self) -> bool {
match self {
CompilerFlavor::Idris2 => true,
_ => false,
}
}
}