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 pub async fn get_or_start_lsp(&self) -> anyhow::Result<Arc<LspClient>> {
23 {
24 let lock = self.lsp_client.read().await;
25 if let Some(client) = lock.as_ref() {
26 return Ok(client.clone());
27 }
28 }
29
30 let mut lock = self.lsp_client.write().await;
31 if let Some(client) = lock.as_ref() {
32 return Ok(client.clone());
33 }
34
35 let client = Arc::new(LspClient::start(&self.workspace_root).await?);
36 *lock = Some(client.clone());
37 Ok(client)
38 }
39
40 pub async fn refresh_lsp(&self) -> anyhow::Result<()> {
41 let mut lock = self.lsp_client.write().await;
42 *lock = None;
43 let client = Arc::new(LspClient::start(&self.workspace_root).await?);
44 *lock = Some(client);
45 Ok(())
46 }
47}