use std::fmt;
use std::process::exit;
use colored::*;
use failure::Fail;
use crate::builder::{BuildStatus, Builder};
use crate::error::*;
pub struct CargoAdapter {
env_name: String,
}
impl CargoAdapter {
pub fn with_env_var<S: AsRef<str>>(env_name: S) -> Self {
CargoAdapter {
env_name: env_name.as_ref().to_string(),
}
}
#[allow(clippy::needless_pass_by_value)]
pub fn build(&self, builder: Builder) -> ! {
if let Err(error) = self.build_inner(&builder) {
eprintln!("{}", ErrorLogPrinter::print(error));
exit(1);
} else {
exit(0);
}
}
fn build_inner(&self, builder: &Builder) -> Result<()> {
match builder.build()? {
BuildStatus::Success(output) => {
let dependencies = output.dependencies()?;
println!(
"cargo:rustc-env={}={}",
self.env_name,
output.get_assembly_path().display()
);
for path in dependencies {
println!("cargo:rerun-if-changed={}", path.display());
}
}
BuildStatus::NotNeeded => {
println!("cargo:rustc-env={}=/dev/null", self.env_name);
}
};
Ok(())
}
}
pub struct ErrorLogPrinter {
error: Box<dyn Fail>,
colors: bool,
}
impl ErrorLogPrinter {
pub fn print(error: Error) -> Self {
Self {
error: Box::new(error),
colors: true,
}
}
pub fn disable_colors(&mut self) -> &mut Self {
self.colors = false;
self
}
}
trait StringExt {
fn prefix_each_line<T>(self, prefix: T) -> Self
where
T: ToString;
}
impl StringExt for String {
fn prefix_each_line<T: ToString>(self, prefix: T) -> Self {
let owned_prefix = prefix.to_string();
let glue = String::from("\n") + &owned_prefix;
owned_prefix + &self.split('\n').collect::<Vec<_>>().join(&glue)
}
}
impl fmt::Display for ErrorLogPrinter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
control::set_override(self.colors);
write!(
f,
"{}",
self.error
.to_string()
.prefix_each_line("[PTX] ".bright_black())
)?;
for next in self.error.iter_causes() {
write!(
f,
"\n{}",
String::from("\n caused by:").prefix_each_line("[PTX]".bright_black())
)?;
write!(
f,
"\n{}",
next.to_string().prefix_each_line("[PTX] ".bright_black())
)?;
}
control::unset_override();
Ok(())
}
}