use crate::build;
use crate::log::Level;
use crate::session::{ColorConfig, Session};
use std::default::Default;
use std::env;
use std::env::current_dir;
use std::error::Error;
use std::path::{Path, PathBuf};
use std::rc::Rc;
#[derive(Clone, Default)]
pub struct Configuration {
session: Session,
}
impl Configuration {
pub fn new() -> Configuration {
Configuration::default()
}
pub fn always_use_colors(&mut self) -> &mut Configuration {
self.session.color_config = ColorConfig::Yes;
self
}
pub fn never_use_colors(&mut self) -> &mut Configuration {
self.session.color_config = ColorConfig::No;
self
}
pub fn use_colors_if_tty(&mut self) -> &mut Configuration {
self.session.color_config = ColorConfig::IfTty;
self
}
pub fn set_in_dir<P>(&mut self, dir: P) -> &mut Self
where
P: Into<PathBuf>,
{
self.session.in_dir = Some(dir.into());
self
}
pub fn set_out_dir<P>(&mut self, dir: P) -> &mut Self
where
P: Into<PathBuf>,
{
self.session.out_dir = Some(dir.into());
self
}
pub fn use_cargo_dir_conventions(&mut self) -> &mut Self {
self.set_in_dir("src")
.set_out_dir(env::var("OUT_DIR").unwrap());
self
}
pub fn generate_in_source_tree(&mut self) -> &mut Self {
self.set_in_dir(Path::new(".")).set_out_dir(Path::new("."))
}
pub fn force_build(&mut self, val: bool) -> &mut Configuration {
self.session.force_build = val;
self
}
pub fn emit_rerun_directives(&mut self, val: bool) -> &mut Configuration {
self.session.emit_rerun_directives = val;
self
}
pub fn emit_comments(&mut self, val: bool) -> &mut Configuration {
self.session.emit_comments = val;
self
}
pub fn emit_whitespace(&mut self, val: bool) -> &mut Configuration {
self.session.emit_whitespace = val;
self
}
pub fn emit_report(&mut self, val: bool) -> &mut Configuration {
self.session.emit_report = val;
self
}
pub fn log_quiet(&mut self) -> &mut Configuration {
self.session.log.set_level(Level::Taciturn);
self
}
pub fn log_info(&mut self) -> &mut Configuration {
self.session.log.set_level(Level::Informative);
self
}
pub fn log_verbose(&mut self) -> &mut Configuration {
self.session.log.set_level(Level::Verbose);
self
}
pub fn log_debug(&mut self) -> &mut Configuration {
self.session.log.set_level(Level::Debug);
self
}
pub fn set_features<I>(&mut self, iterable: I) -> &mut Configuration
where
I: IntoIterator<Item = String>,
{
self.session.features = Some(iterable.into_iter().collect());
self
}
#[doc(hidden)]
pub fn unit_test(&mut self) -> &mut Configuration {
self.session.unit_test = true;
self
}
pub fn process(&self) -> Result<(), Box<dyn Error>> {
let root = if let Some(ref d) = self.session.in_dir {
d.as_path()
} else {
Path::new(".")
};
self.process_dir(root)
}
pub fn process_current_dir(&self) -> Result<(), Box<dyn Error>> {
self.process_dir(current_dir()?)
}
pub fn process_dir<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn Error>> {
let mut session = self.session.clone();
if session.in_dir.is_none() {
let mut in_dir = env::current_dir()?;
in_dir.push("src");
session.in_dir = Some(in_dir);
}
if session.out_dir.is_none() {
let out_dir = match env::var_os("OUT_DIR") {
Some(var) => var,
None => return Err("missing OUT_DIR variable")?,
};
session.out_dir = Some(PathBuf::from(out_dir));
}
if self.session.features.is_none() {
session.features = Some(
env::vars()
.filter_map(|(feature_var, _)| {
let prefix = "CARGO_FEATURE_";
if feature_var.starts_with(prefix) {
Some(
feature_var[prefix.len()..]
.replace("_", "-")
.to_ascii_lowercase(),
)
} else {
None
}
})
.collect(),
);
}
let session = Rc::new(session);
build::process_dir(session, path)?;
Ok(())
}
pub fn process_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn Error>> {
let session = Rc::new(self.session.clone());
build::process_file(session, path)?;
Ok(())
}
}
pub fn process_root() -> Result<(), Box<dyn Error>> {
Configuration::new().process_current_dir()
}
pub fn process_root_unconditionally() -> Result<(), Box<dyn Error>> {
Configuration::new().force_build(true).process_current_dir()
}