use serde::{Deserialize, Serialize};
use std::{
env, fs,
path::{Path, PathBuf},
};
mod cfg_trait;
mod dependencies;
mod global_config;
mod pkg_config;
mod toolchain;
use crate::error::EmbargoError;
pub use cfg_trait::ConfigFile;
use dependencies::EmbargoDependenciesConfig;
use pkg_config::EmbargoPackageConfig;
#[derive(Serialize, Deserialize, Debug, Default, Hash)]
pub struct EmbargoFile {
pub package: EmbargoPackageConfig,
pub dependencies: Option<EmbargoDependenciesConfig>,
}
impl EmbargoFile {
pub fn read_file(dir: Option<&Path>) -> Result<(Self, PathBuf), EmbargoError> {
let cwd = if let Some(d) = dir {
let file = Self::default();
let mut path = d.to_owned();
path.push("Embargo.toml");
return Ok((file, path));
} else {
env::current_dir()?
};
let mut path = match find_embargo_file_path(&cwd) {
Some(p) => p,
None => {
return Err(EmbargoError::new("Unable to locate Embargo.toml"));
}
};
let file = fs::read_to_string(&path)?;
path.pop(); Ok((toml::from_str(&file)?, path))
}
}
impl<'a> ConfigFile<'a> for EmbargoFile {
fn compiler(&'a self) -> &'a str {
self.package.compiler()
}
fn linker(&'a self) -> &'a str {
self.package.linker()
}
fn source_path(&'a self) -> &'a str {
self.package.source_path()
}
fn build_path(&'a self) -> &'a str {
self.package.build_path()
}
fn auto_clean(&'a self) -> bool {
self.package.auto_clean()
}
fn object_path(&'a self) -> &'a str {
self.package.object_path()
}
fn target_path_debug(&'a self) -> &'a str {
self.package.target_path_debug()
}
fn target_path_release(&'a self) -> &'a str {
self.package.target_path_release()
}
fn bin_path(&'a self) -> &'a str {
self.package.bin_path()
}
fn lib_path(&'a self) -> &'a str {
self.package.lib_path()
}
fn flags(&'a self) -> &'a [String] {
self.package.flags()
}
fn args(&'a self) -> &'a [String] {
self.package.args()
}
fn author(&'a self) -> Option<&'a str> {
self.package.author()
}
}
fn find_embargo_file_path(path: &Path) -> Option<PathBuf> {
if let Ok(entry) = path.read_dir() {
return match entry
.into_iter()
.filter_map(|e| e.ok())
.find(|e| e.file_name().eq_ignore_ascii_case("Embargo.toml"))
{
Some(entry) => Some(entry.path()),
None => {
let mut p = path.to_path_buf();
if p.pop() {
find_embargo_file_path(&p)
} else {
None
}
}
};
}
None
}