rust_analyzer_cli/daemon/
state.rs1use crate::lsp::client::LspClient;
2use std::path::PathBuf;
3use std::sync::Arc;
4use tokio::sync::RwLock;
5
6pub struct AppState {
7 pub workspace_root: PathBuf,
8 pub lsp_client: Arc<RwLock<Option<Arc<LspClient>>>>,
9}
10
11impl AppState {
12 pub fn new(workspace_root: PathBuf) -> Self {
13 let canonical_root = workspace_root
14 .canonicalize()
15 .unwrap_or_else(|_| workspace_root.clone());
16 Self {
17 workspace_root: canonical_root,
18 lsp_client: Arc::new(RwLock::new(None)),
19 }
20 }
21
22
23 pub async fn get_or_start_lsp(&self) -> anyhow::Result<Arc<LspClient>> {
24 {
25 let lock = self.lsp_client.read().await;
26 if let Some(client) = lock.as_ref() {
27 return Ok(client.clone());
28 }
29 }
30
31 let mut lock = self.lsp_client.write().await;
32 if let Some(client) = lock.as_ref() {
33 return Ok(client.clone());
34 }
35
36 let client = Arc::new(LspClient::start(&self.workspace_root).await?);
37 *lock = Some(client.clone());
38 Ok(client)
39 }
40
41 pub async fn refresh_lsp(&self) -> anyhow::Result<()> {
42 let mut lock = self.lsp_client.write().await;
43 *lock = None;
44 let client = Arc::new(LspClient::start(&self.workspace_root).await?);
45 *lock = Some(client);
46 Ok(())
47 }
48}