use std::{fmt::Display, path::PathBuf, sync::Arc};
use arcstr::Substr;
use crate::{bsc::args::BscArgs, project::Project};
use super::{FileHandle, PkgHandle, bo_for_source};
pub struct Package {
pub file: FileHandle,
pub cli: Arc<BscArgs>,
pub bo_path: Option<PathBuf>,
pub name: Option<Substr>,
}
impl Display for Package {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(bo) = &self.bo_path {
write!(f, "'{}'", bo.display())
} else {
write!(f, "<anonymous pacakge for {:?}>", self.file)
}
}
}
impl Package {
pub fn new(file: FileHandle, cli: Arc<BscArgs>, bo_path: Option<PathBuf>) -> Self {
let name = bo_path
.as_deref()
.and_then(|bo| bo.file_stem().and_then(|s| s.to_str()).map(str::to_owned))
.map(Substr::from);
Package {
file,
cli,
bo_path,
name,
}
}
pub fn resolve_import(&self, proj: &Project, name: &str) -> Option<PkgHandle> {
let search_paths = |ext: &str| {
for dir in &self.cli.include_dirs {
let path = dir.join(name).with_extension(ext);
if path.is_file() {
return Some(path);
}
}
None
};
if let Some(bsv) = search_paths("bsv") {
return bo_for_source(bsv, self.cli.bdir.as_deref())
.and_then(|bo| proj.pkg_for_bo(&bo));
}
if let Some(bs) = search_paths("bs") {
return bo_for_source(bs, self.cli.bdir.as_deref()).and_then(|bo| proj.pkg_for_bo(&bo));
}
if let Some(bo) = search_paths("bo") {
return proj.pkg_for_bo(&bo);
}
None
}
}