code_moniker_workspace/registry/
staleness.rs1use std::path::PathBuf;
2
3use crate::live::WorkspaceLiveRefreshPlan;
4
5#[derive(Clone, Debug, Default, Eq, PartialEq)]
6pub struct WorkspaceStaleness {
7 pub stale_paths: Vec<PathBuf>,
8 pub requires_rescan: bool,
9 pub git_base_stale: bool,
10}
11
12impl WorkspaceStaleness {
13 pub fn from_plan(plan: &WorkspaceLiveRefreshPlan) -> Self {
14 Self {
15 stale_paths: plan.source_paths().to_vec(),
16 requires_rescan: plan.requires_rescan(),
17 git_base_stale: plan.includes_git_base(),
18 }
19 }
20
21 pub fn is_stale(&self) -> bool {
22 self.requires_rescan || !self.stale_paths.is_empty() || self.git_base_stale
23 }
24
25 pub fn summary(&self) -> String {
26 summary_parts(
27 self.stale_paths.len(),
28 self.requires_rescan,
29 self.git_base_stale,
30 )
31 }
32
33 pub fn plan_summary(plan: &WorkspaceLiveRefreshPlan) -> String {
34 summary_parts(
35 plan.source_paths().len(),
36 plan.requires_rescan(),
37 plan.includes_git_base(),
38 )
39 }
40}
41
42fn summary_parts(stale_paths: usize, requires_rescan: bool, git_base_stale: bool) -> String {
43 if requires_rescan {
44 return "rescan required".to_string();
45 }
46 let mut parts = Vec::new();
47 if stale_paths > 0 {
48 parts.push(format!("{stale_paths} stale path(s)"));
49 }
50 if git_base_stale {
51 parts.push("git base changed".to_string());
52 }
53 if parts.is_empty() {
54 return "fresh".to_string();
55 }
56 parts.join(", ")
57}