use std::fs::read_to_string;
use std::path::{Path, PathBuf};
use cargo_toml::{Manifest, Product};
use crate::directives::DirectiveVisibility;
use crate::formats::Format;
pub(crate) fn check_for_manifest(paths: Vec<&Path>) -> Option<(PathBuf, CargoManifest)> {
for path in paths {
let manifest_path = path.join("Cargo.toml");
if manifest_path.is_file() {
return Some((
path.into(),
CargoManifest(Manifest::from_path(manifest_path).unwrap()),
));
}
}
None
}
#[derive(Clone, Debug)]
pub(crate) struct SourceCodeFile {
pub(crate) path: PathBuf,
pub(crate) item: String,
}
impl SourceCodeFile {
pub(crate) fn ast(&self) -> syn::File {
syn::parse_file(&read_to_string(&self.path).unwrap()).unwrap()
}
pub(crate) fn to_parent_directory(&self) -> Self {
SourceCodeFile {
path: self.path.parent().as_ref().unwrap().into(),
item: self.item.clone(),
}
}
fn from_product(prd: &Product, crate_dir: &Path) -> Self {
SourceCodeFile {
path: crate_dir.join(prd.path.as_ref().unwrap()),
item: prd.name.as_ref().unwrap().clone(),
}
}
pub(crate) fn crate_name(&self) -> &str {
&self.item[0..self.item.find("::").unwrap_or(self.item.len())]
}
}
pub(crate) struct CargoManifest(Manifest);
impl CargoManifest {
pub(crate) fn lib_file(&self, crate_dir: &Path) -> Option<SourceCodeFile> {
self.0
.lib
.as_ref()
.map(|lib| SourceCodeFile::from_product(lib, crate_dir))
}
pub(crate) fn executable_files(&self, crate_dir: &Path) -> Vec<SourceCodeFile> {
self.0
.bin
.iter()
.map(|prd| SourceCodeFile::from_product(prd, crate_dir))
.collect()
}
}
pub(crate) trait FileTopLevelDirective {
fn get_doc_file(&self) -> &Path;
fn get_text(self, format: &Format, max_visibility: &DirectiveVisibility) -> Vec<String>;
}