use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use path_clean::PathClean;
use crate::Manifest;
use crate::dependency::DependencyName;
use crate::manifest::ManifestError;
pub fn is_module_root(dir: &Path) -> bool {
dir.join(crate::MANIFEST_FILENAME).is_file()
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct ModuleId {
pub root: PathBuf,
pub scope: Vec<DependencyName>,
}
#[derive(Clone, Debug)]
pub struct Module {
pub manifest: Arc<Manifest>,
pub root: PathBuf,
pub lockfile_scope: Vec<DependencyName>,
}
impl Module {
pub fn new(manifest: Arc<Manifest>, root: PathBuf) -> Self {
Self {
manifest,
root,
lockfile_scope: Vec::new(),
}
}
pub fn id(&self) -> ModuleId {
ModuleId {
root: self.root.clone(),
scope: self.lockfile_scope.clone(),
}
}
pub fn load_from_path(path: &Path) -> Result<Self, ManifestError> {
let manifest_path = path.join(crate::MANIFEST_FILENAME);
let bytes = std::fs::read(&manifest_path).map_err(|source| ManifestError::Io {
path: manifest_path,
source,
})?;
let manifest = Arc::new(Manifest::parse(&bytes)?);
Ok(Self::new(manifest, path.to_path_buf()))
}
pub fn resolve_local_path(&self, path: &Path) -> PathBuf {
if path.is_absolute() {
path.clean()
} else {
self.root.join(path).clean()
}
}
pub fn child(&self, name: DependencyName, manifest: Arc<Manifest>, root: PathBuf) -> Self {
let mut lockfile_scope = self.lockfile_scope.clone();
lockfile_scope.push(name);
Self {
manifest,
root,
lockfile_scope,
}
}
}