1use dashmap::DashMap;
7use lsp_types::{Location, Url};
8use std::sync::{Arc, RwLock};
9
10#[derive(Debug, Clone)]
12pub struct SymbolInfo {
13 pub name: String,
15 pub symbol_type: SymbolType,
17 pub location: Location,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum SymbolType {
24 Struct,
26 Function,
28 Const,
30 Static,
32 Module,
34}
35
36#[derive(Debug, Clone)]
38pub struct SymbolIndex {
39 pub symbols: DashMap<String, Vec<SymbolInfo>>,
41}
42
43impl SymbolIndex {
44 pub fn new() -> Self {
46 Self {
47 symbols: DashMap::new(),
48 }
49 }
50
51 pub fn add(&self, name: String, info: SymbolInfo) {
53 self.symbols.entry(name).or_default().push(info);
54 }
55
56 pub fn find(&self, name: &str) -> Vec<SymbolInfo> {
58 self.symbols
59 .get(name)
60 .map(|v| v.clone())
61 .unwrap_or_default()
62 }
63
64 pub fn clear(&self) {
66 self.symbols.clear();
67 }
68}
69
70impl Default for SymbolIndex {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76#[derive(Debug, Clone)]
78pub struct ComponentInfo {
79 pub name: String,
81 pub type_name: String,
83 pub location: Location,
85 pub plugin: Option<String>,
87}
88
89#[derive(Debug, Clone)]
91pub struct ComponentIndex {
92 pub components: DashMap<String, ComponentInfo>,
94}
95
96impl ComponentIndex {
97 pub fn new() -> Self {
99 Self {
100 components: DashMap::new(),
101 }
102 }
103
104 pub fn add(&self, name: String, info: ComponentInfo) {
106 self.components.insert(name, info);
107 }
108
109 pub fn find(&self, name: &str) -> Option<ComponentInfo> {
111 self.components.get(name).map(|v| v.clone())
112 }
113
114 pub fn clear(&self) {
116 self.components.clear();
117 }
118}
119
120impl Default for ComponentIndex {
121 fn default() -> Self {
122 Self::new()
123 }
124}
125
126pub struct Workspace {
128 pub root_uri: Url,
130 pub documents: Vec<(Url, String)>,
132}
133
134pub struct IndexManager {
139 symbol_index: Arc<RwLock<SymbolIndex>>,
141 route_index: Arc<RwLock<crate::route::RouteIndex>>,
143 component_index: Arc<RwLock<ComponentIndex>>,
145}
146
147impl IndexManager {
148 pub fn new() -> Self {
150 Self {
151 symbol_index: Arc::new(RwLock::new(SymbolIndex::new())),
152 route_index: Arc::new(RwLock::new(crate::route::RouteIndex::new())),
153 component_index: Arc::new(RwLock::new(ComponentIndex::new())),
154 }
155 }
156
157 pub async fn build(&self, workspace: &Workspace) {
162 let symbol_index = self.symbol_index.clone();
163 let route_index = self.route_index.clone();
164 let component_index = self.component_index.clone();
165
166 let root_uri = workspace.root_uri.clone();
168 let documents = workspace.documents.clone();
169
170 tokio::spawn(async move {
171 let new_symbols = Self::build_symbol_index(&root_uri, &documents).await;
173 let new_routes = Self::build_route_index(&root_uri, &documents).await;
174 let new_components = Self::build_component_index(&root_uri, &documents).await;
175
176 *symbol_index
178 .write()
179 .expect("Failed to acquire write lock on symbol index") = new_symbols;
180 *route_index
181 .write()
182 .expect("Failed to acquire write lock on route index") = new_routes;
183 *component_index
184 .write()
185 .expect("Failed to acquire write lock on component index") = new_components;
186
187 tracing::info!("Index rebuild completed");
188 });
189 }
190
191 pub fn update(&self, uri: &Url, _content: &str) {
195 tracing::debug!("Updating index for {}", uri);
199
200 }
205
206 pub fn find_symbol(&self, name: &str) -> Vec<SymbolInfo> {
208 let index = self
209 .symbol_index
210 .read()
211 .expect("Failed to acquire read lock on symbol index");
212 index.find(name)
213 }
214
215 pub fn find_component(&self, name: &str) -> Option<ComponentInfo> {
217 let index = self
218 .component_index
219 .read()
220 .expect("Failed to acquire read lock on component index");
221 index.find(name)
222 }
223
224 pub fn get_all_routes(&self) -> Vec<crate::route::RouteInfo> {
226 let index = self
227 .route_index
228 .read()
229 .expect("Failed to acquire read lock on route index");
230 index.routes.clone()
231 }
232
233 async fn build_symbol_index(_root_uri: &Url, _documents: &[(Url, String)]) -> SymbolIndex {
235 SymbolIndex::new()
240 }
241
242 async fn build_route_index(
244 _root_uri: &Url,
245 _documents: &[(Url, String)],
246 ) -> crate::route::RouteIndex {
247 crate::route::RouteIndex::new()
252 }
253
254 async fn build_component_index(
256 _root_uri: &Url,
257 _documents: &[(Url, String)],
258 ) -> ComponentIndex {
259 ComponentIndex::new()
264 }
265}
266
267impl Default for IndexManager {
268 fn default() -> Self {
269 Self::new()
270 }
271}