(
&self,
project_id: &str,
)
| 54 | } |
| 55 | |
| 56 | pub(crate) async fn selected_project_state( |
| 57 | &self, |
| 58 | project_id: &str, |
| 59 | ) -> Result<SelectedProjectState> { |
| 60 | if self.active.project_id.as_deref() == Some(project_id) { |
| 61 | return Ok(SelectedProjectState { |
| 62 | state: self.active.clone(), |
| 63 | }); |
| 64 | } |
| 65 | |
| 66 | let db = GlobalDb::open() |
| 67 | .await |
| 68 | .ok_or_else(|| config_error("could not open tracedecay project registry"))?; |
| 69 | let context = db |
| 70 | .project_registry_context_by_id(project_id) |
| 71 | .await |
| 72 | .ok_or_else(|| config_error(format!("registered project not found: {project_id}")))?; |
| 73 | if let Some(cached) = self.project_states.read().await.get(project_id).cloned() { |
| 74 | if cached.registry_context == context { |
| 75 | return Ok(SelectedProjectState { |
| 76 | state: cached.state, |
| 77 | }); |
| 78 | } |
| 79 | } |
| 80 | let project_root = PathBuf::from(&context.project.canonical_root); |
| 81 | let cg = TraceDecay::open_read_only(&project_root).await?; |
| 82 | if cg.store_layout().identity.project_id.as_deref() != Some(project_id) { |
| 83 | return Err(config_error(format!( |
| 84 | "registered project id mismatch for {project_id}: {}", |
| 85 | project_root.display() |
| 86 | ))); |
| 87 | } |
| 88 | let state = build_selected_project_state(&cg).await; |
| 89 | let mut project_states = self.project_states.write().await; |
| 90 | if let Some(cached) = project_states.get(project_id).cloned() { |
| 91 | if cached.registry_context == context { |
| 92 | return Ok(SelectedProjectState { |
| 93 | state: cached.state, |
| 94 | }); |
| 95 | } |
| 96 | } |
| 97 | project_states.insert( |
| 98 | project_id.to_string(), |
| 99 | CachedProjectState { |
| 100 | registry_context: context, |
| 101 | state: state.clone(), |
| 102 | }, |
| 103 | ); |
| 104 | Ok(SelectedProjectState { state }) |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | pub(crate) struct SelectedProjectState { |
no test coverage detected