use time;
use uuid;
use crate::conf::DumpCodeConfig;
use crate::error::*;
use std::fs::OpenOptions;
use std::io::Error as IOError;
use std::io::Write;
use std::path::PathBuf;
use uuid::Uuid;
impl From<IOError> for WeldCompileError {
fn from(err: IOError) -> WeldCompileError {
WeldCompileError::new(err.to_string())
}
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum DumpCodeFormat {
Weld,
WeldOpt,
LLVM,
LLVMOpt,
SIR,
Assembly,
}
impl DumpCodeFormat {
pub fn all() -> Vec<DumpCodeFormat> {
use self::DumpCodeFormat::*;
vec![Weld, WeldOpt, LLVM, LLVMOpt, SIR, Assembly]
}
pub fn suffix(self) -> String {
use self::DumpCodeFormat::*;
match self {
WeldOpt | LLVMOpt => "-opt",
_ => "",
}
.to_string()
}
pub fn extension(self) -> String {
use self::DumpCodeFormat::*;
match self {
Weld | WeldOpt => "weld",
LLVM | LLVMOpt => "ll",
SIR => "sir",
Assembly => "S",
}
.to_string()
}
}
pub fn write_code<T: AsRef<str>>(
code: T,
format: DumpCodeFormat,
config: &DumpCodeConfig,
) -> WeldResult<()> {
if !config.enabled {
return Ok(());
}
if !config.formats.contains(&format) {
return Ok(());
}
let path = &mut PathBuf::new();
path.push(&config.directory);
path.push(&format!("{}{}", &config.filename, format.suffix()));
path.set_extension(format.extension());
info!("Writing code to {}", path.to_str().unwrap());
let mut options = OpenOptions::new();
let mut file = options.write(true).create_new(true).open(path)?;
file.write_all(code.as_ref().as_bytes())?;
Ok(())
}
pub fn unique_filename() -> String {
let uuid = Uuid::new_v4().to_simple().to_string();
let suffix = &uuid[0..2];
format!("code-{}-{}", time::now().to_timespec().sec, suffix)
}