use anyhow::Context;
#[derive(Debug, Clone)]
pub(crate) struct Manifest {
pub(crate) path: std::path::PathBuf,
pub(crate) parsed: cargo_toml::Manifest,
}
impl Manifest {
pub(crate) fn parse(path: std::path::PathBuf) -> anyhow::Result<Self> {
let parsed = cargo_toml::Manifest::from_path(&path)
.with_context(|| format!("Failed when reading {}", path.display()))?;
Ok(Self { path, parsed })
}
}
pub(crate) fn get_package_name(manifest: &Manifest) -> anyhow::Result<&str> {
let package = manifest.parsed.package.as_ref().ok_or_else(|| {
anyhow::format_err!(
"Failed to parse {}: no `package` table",
manifest.path.display()
)
})?;
Ok(&package.name)
}
pub(crate) fn get_package_version(manifest: &Manifest) -> anyhow::Result<&str> {
let package = manifest.parsed.package.as_ref().ok_or_else(|| {
anyhow::format_err!(
"Failed to parse {}: no `package` table",
manifest.path.display()
)
})?;
let version = package.version.get().with_context(|| {
format!(
"Failed to retrieve package version from {}",
manifest.path.display(),
)
})?;
Ok(version)
}
pub(crate) fn get_lib_target_name(manifest: &Manifest) -> anyhow::Result<String> {
if let Some(product) = &manifest.parsed.lib {
if let Some(lib_name) = &product.name {
return Ok(lib_name.clone());
}
}
Ok(get_package_name(manifest)?.replace('-', "_"))
}
pub(crate) fn get_first_bin_target_name(manifest: &Manifest) -> anyhow::Result<String> {
if let Some(product) = manifest.parsed.bin.first() {
if let Some(bin_name) = &product.name {
return Ok(bin_name.clone());
}
}
Ok(get_package_name(manifest)?.replace('-', "_"))
}
pub(crate) fn get_project_dir_from_manifest_path(
manifest_path: &std::path::Path,
) -> anyhow::Result<std::path::PathBuf> {
assert!(
manifest_path.ends_with("Cargo.toml"),
"path {} isn't pointing to a manifest",
manifest_path.display()
);
let dir_path = manifest_path
.parent()
.context("manifest path doesn't have a parent")?;
Ok(dir_path.to_path_buf())
}