use super::info::Visibility;
use super::info::WorktreeHealth;
use super::package::PackageProject;
use super::paths::AbsolutePath;
use super::project_fields::ProjectFields;
use super::workspace::WorkspaceProject;
use crate::lint::LintStatus;
#[derive(Clone)]
pub(crate) enum WorktreeGroup {
Workspaces {
primary: WorkspaceProject,
linked: Vec<WorkspaceProject>,
},
Packages {
primary: PackageProject,
linked: Vec<PackageProject>,
},
}
impl WorktreeGroup {
pub(crate) const fn new_workspaces(
primary: WorkspaceProject,
linked: Vec<WorkspaceProject>,
) -> Self {
Self::Workspaces { primary, linked }
}
pub(crate) const fn new_packages(primary: PackageProject, linked: Vec<PackageProject>) -> Self {
Self::Packages { primary, linked }
}
pub(crate) fn primary_path(&self) -> &AbsolutePath {
match self {
Self::Workspaces { primary, .. } => primary.path(),
Self::Packages { primary, .. } => primary.path(),
}
}
pub(crate) fn derived_visibility(&self) -> Visibility {
let visible_entries = self.visible_entry_count();
if visible_entries > 0 {
return Visibility::Visible;
}
if self.has_deleted_entry() {
return Visibility::Deleted;
}
Visibility::Dismissed
}
pub(crate) fn primary_worktree_health(&self) -> WorktreeHealth {
match self {
Self::Workspaces { primary, .. } => primary.worktree_health(),
Self::Packages { primary, .. } => primary.worktree_health(),
}
}
pub(crate) fn live_entry_count(&self) -> usize {
match self {
Self::Workspaces {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(WorkspaceProject::visibility))
.filter(|v| !matches!(v, Visibility::Dismissed))
.count(),
Self::Packages {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(PackageProject::visibility))
.filter(|v| !matches!(v, Visibility::Dismissed))
.count(),
}
}
fn has_deleted_entry(&self) -> bool {
match self {
Self::Workspaces {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(WorkspaceProject::visibility))
.any(|visibility| visibility == Visibility::Deleted),
Self::Packages {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(PackageProject::visibility))
.any(|visibility| visibility == Visibility::Deleted),
}
}
fn visible_entry_count(&self) -> usize {
match self {
Self::Workspaces {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(WorkspaceProject::visibility))
.filter(|visibility| *visibility == Visibility::Visible)
.count(),
Self::Packages {
primary, linked, ..
} => std::iter::once(primary.visibility())
.chain(linked.iter().map(PackageProject::visibility))
.filter(|visibility| *visibility == Visibility::Visible)
.count(),
}
}
pub(crate) fn renders_as_group(&self) -> bool { self.live_entry_count() > 1 }
pub(crate) fn single_live_workspace(&self) -> Option<&WorkspaceProject> {
match self {
Self::Workspaces {
primary, linked, ..
} => super::root_item::single_live_workspace(primary, linked),
Self::Packages { .. } => None,
}
}
pub(crate) fn single_live_package(&self) -> Option<&PackageProject> {
match self {
Self::Packages {
primary, linked, ..
} => super::root_item::single_live_package(primary, linked),
Self::Workspaces { .. } => None,
}
}
pub(crate) fn lint_rollup_status(&self) -> LintStatus {
let statuses: Vec<LintStatus> = match self {
Self::Workspaces {
primary, linked, ..
} => std::iter::once(primary.lint_runs().status())
.chain(
linked
.iter()
.filter(|l| l.visibility() == Visibility::Visible)
.map(|l| l.lint_runs().status()),
)
.cloned()
.collect(),
Self::Packages {
primary, linked, ..
} => std::iter::once(primary.lint_runs().status())
.chain(
linked
.iter()
.filter(|l| l.visibility() == Visibility::Visible)
.map(|l| l.lint_runs().status()),
)
.cloned()
.collect(),
};
let running: Vec<LintStatus> = statuses
.iter()
.filter(|s| matches!(s, LintStatus::Running(_)))
.cloned()
.collect();
if !running.is_empty() {
return LintStatus::aggregate(running);
}
LintStatus::aggregate(statuses)
}
pub(crate) fn lint_status_for_worktree(&self, worktree_index: usize) -> LintStatus {
match self {
Self::Workspaces {
primary, linked, ..
} => {
if worktree_index == 0 {
primary.lint_runs().status().clone()
} else {
linked
.get(worktree_index - 1)
.map_or(LintStatus::NoLog, |l| l.lint_runs().status().clone())
}
},
Self::Packages {
primary, linked, ..
} => {
if worktree_index == 0 {
primary.lint_runs().status().clone()
} else {
linked
.get(worktree_index - 1)
.map_or(LintStatus::NoLog, |l| l.lint_runs().status().clone())
}
},
}
}
}