use crate::config::Config;
use crate::error::{Error, Result};
use crate::manifest::Manifest;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
pub fn list_rust_files(dir: &Path) -> Result<Vec<PathBuf>> {
let mut files = vec![];
if dir.exists() && dir.is_dir() {
let entries = std::fs::read_dir(dir).map_err(|e| Error::Io(dir.to_owned(), e))?;
for entry in entries {
let path = entry.map_err(|e| Error::Io(dir.to_owned(), e))?.path();
if path.is_file() && path.extension() == Some(OsStr::new("rs")) {
files.push(path);
}
}
}
Ok(files)
}
pub fn canonicalize(mut path: &Path) -> Result<PathBuf> {
if path == Path::new("") {
path = Path::new(".");
}
dunce::canonicalize(path).map_err(|e| Error::Io(path.to_owned(), e))
}
pub fn find_package_manifest_in_workspace(
(workspace_manifest_path, workspace_manifest): &(PathBuf, Manifest),
(potential_manifest_path, potential_manifest): (PathBuf, Manifest),
package_name: Option<&str>,
) -> Result<(PathBuf, Manifest)> {
let potential_manifest_dir = potential_manifest_path.parent().unwrap();
let workspace_manifest_dir = workspace_manifest_path.parent().unwrap();
let workspace_members = workspace_manifest.members(workspace_manifest_dir)?;
if workspace_manifest_path != &potential_manifest_path
&& !workspace_members.contains_key(potential_manifest_dir)
{
return Err(Error::ManifestNotInWorkspace {
manifest: potential_manifest_path,
workspace_manifest: workspace_manifest_path.clone(),
});
}
match package_name {
Some(name) => {
if let Some(package) = &workspace_manifest.package {
if package.name == name {
return Ok((
workspace_manifest_path.to_owned(),
workspace_manifest.clone(),
));
}
}
for (_manifest_dir, (manifest_path, manifest)) in workspace_members {
let package = manifest.package.as_ref().unwrap();
if package.name == name {
return Ok((manifest_path, manifest));
}
}
Err(Error::PackageNotFound(
workspace_manifest_path.clone(),
name.to_owned(),
))
}
None => {
if potential_manifest.package.is_none() {
return Err(Error::NoPackageInManifest(potential_manifest_path));
}
Ok((potential_manifest_path, potential_manifest))
}
}
}
pub fn find_manifest(path: &Path) -> Result<(PathBuf, Manifest)> {
let path = canonicalize(path)?;
let manifest_path = path
.ancestors()
.map(|dir| dir.join("Cargo.toml"))
.find(|manifest| manifest.exists())
.ok_or(Error::ManifestNotFound)?;
let manifest = Manifest::parse_from_toml(&manifest_path)?;
Ok((manifest_path, manifest))
}
pub fn find_workspace(potential_root: &Path) -> Result<Option<(PathBuf, Manifest)>> {
let potential_root = canonicalize(potential_root)?;
for manifest_path in potential_root
.ancestors()
.map(|dir| dir.join("Cargo.toml"))
.filter(|manifest| manifest.exists())
{
let manifest = Manifest::parse_from_toml(&manifest_path)?;
if manifest.workspace.is_some() {
return Ok(Some((manifest_path, manifest)));
}
}
Ok(None)
}
pub fn get_target_dir_name(config: Option<&Config>) -> Result<String> {
if let Some(config) = config {
if let Some(build) = config.build.as_ref() {
if let Some(target_dir) = &build.target_dir {
return Ok(target_dir.clone());
}
}
}
Ok("target".to_string())
}