#![warn(missing_docs)]
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use package_json::PackageJson;
use crate::monorepo::WorkspacePackage;
use crate::node::PackageManager;
use super::{ProjectInfo, ProjectKind, ProjectValidationStatus};
#[derive(Debug, Clone, Default)]
pub struct Dependencies {
pub prod: HashMap<String, String>,
pub dev: HashMap<String, String>,
pub peer: HashMap<String, String>,
pub optional: HashMap<String, String>,
}
impl Dependencies {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn total_count(&self) -> usize {
self.prod.len() + self.dev.len() + self.peer.len() + self.optional.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.total_count() == 0
}
pub fn all_dependencies(&self) -> impl Iterator<Item = (&str, &str, &'static str)> {
self.prod
.iter()
.map(|(k, v)| (k.as_str(), v.as_str(), "prod"))
.chain(self.dev.iter().map(|(k, v)| (k.as_str(), v.as_str(), "dev")))
.chain(self.peer.iter().map(|(k, v)| (k.as_str(), v.as_str(), "peer")))
.chain(self.optional.iter().map(|(k, v)| (k.as_str(), v.as_str(), "optional")))
}
}
#[derive(Debug)]
pub struct Project {
pub root: PathBuf,
pub kind: ProjectKind,
pub package_manager: Option<PackageManager>,
pub package_json: Option<PackageJson>,
pub external_dependencies: Dependencies,
pub internal_dependencies: Vec<WorkspacePackage>,
pub validation_status: ProjectValidationStatus,
}
impl Project {
#[must_use]
pub fn new(root: PathBuf, kind: ProjectKind) -> Self {
Self {
root,
kind,
package_manager: None,
package_json: None,
external_dependencies: Dependencies::default(),
internal_dependencies: Vec::new(),
validation_status: ProjectValidationStatus::NotValidated,
}
}
#[must_use]
pub fn is_monorepo(&self) -> bool {
self.kind.is_monorepo()
}
#[must_use]
pub fn has_internal_dependencies(&self) -> bool {
!self.internal_dependencies.is_empty()
}
pub fn get_all_dependencies(&self) -> impl Iterator<Item = (&str, &str, &'static str)> {
self.external_dependencies.all_dependencies()
}
#[must_use]
pub fn get_workspace_packages(&self) -> &[WorkspacePackage] {
&self.internal_dependencies
}
#[must_use]
pub fn root(&self) -> &Path {
&self.root
}
#[must_use]
pub fn project_type(&self) -> String {
self.kind.name()
}
pub fn set_validation_status(&mut self, status: ProjectValidationStatus) {
self.validation_status = status;
}
}
impl ProjectInfo for Project {
fn root(&self) -> &Path {
&self.root
}
fn package_manager(&self) -> Option<&PackageManager> {
self.package_manager.as_ref()
}
fn package_json(&self) -> Option<&PackageJson> {
self.package_json.as_ref()
}
fn validation_status(&self) -> &ProjectValidationStatus {
&self.validation_status
}
fn kind(&self) -> ProjectKind {
self.kind.clone()
}
}