1use crate::handlers::TransportHandler;
2use crate::Configuration;
3use gveditor_core_api::filesystems::{DirItemInfo, FileInfo, FilesystemErrors};
4use gveditor_core_api::messaging::{ExtensionMessages, Messages};
5use gveditor_core_api::state::{StateData, StatesList};
6use gveditor_core_api::{Errors, LanguageServer, ManifestInfo, Mutex, State};
7use jsonrpc_core::BoxFuture;
8use jsonrpc_derive::rpc;
9
10use std::sync::Arc;
11
12pub struct Server {
13 states: Arc<Mutex<StatesList>>,
14 config: Configuration,
15}
16
17impl Server {
71 pub fn new(mut config: Configuration, states: Arc<Mutex<StatesList>>) -> Self {
79 let receiver = config.receiver.take();
80 let handler = config.handler.clone();
81 let states_list = states.clone();
82
83 tokio::spawn(async move {
84 if let Some(mut receiver) = receiver {
85 loop {
86 if let Some(message) = receiver.recv().await {
87 Self::process_message(states_list.clone(), message, handler.clone()).await;
88 }
89 }
90 }
91 });
92
93 Self { config, states }
94 }
95
96 pub async fn run(&self) {
98 let states = self.states.clone();
99 let mut handler = self.config.handler.lock().await;
100
101 handler
102 .run(states.clone(), self.config.sender.clone())
103 .await;
104 }
105
106 pub async fn process_message(
108 states: Arc<Mutex<StatesList>>,
109 msg: Messages,
110 handler: Arc<Mutex<Box<dyn TransportHandler + Send + Sync>>>,
111 ) {
112 match msg {
113 Messages::ListenToState {
114 state_id,
115 trigger: _,
116 } => {
117 let state = {
119 let states = states.lock().await;
120 states.get_state_by_id(state_id)
121 };
122
123 if let Some(state) = state {
124 let handler = handler.lock().await;
125 let message = Messages::StateUpdated {
127 state_data: state.lock().await.data.clone(),
128 };
129 handler.send(message).await;
130
131 state.lock().await.run_extensions().await;
132 }
133 }
134 Messages::StateUpdated { .. } => {
135 let states = states.lock().await;
136 states
137 .notify_extensions(ExtensionMessages::CoreMessage(msg))
138 .await;
139 }
140 Messages::RegisterLanguageServers {
141 state_id,
142 languages,
143 ..
144 } => {
145 let state = {
146 let states = states.lock().await;
147 states.get_state_by_id(state_id)
148 };
149
150 if let Some(state) = state {
151 state
152 .lock()
153 .await
154 .register_language_servers(languages)
155 .await;
156 }
157 }
158 Messages::NotifyLanguageServers {
159 state_id, message, ..
160 } => {
161 let state = {
162 let states = states.lock().await;
163 states.get_state_by_id(state_id)
164 };
165
166 if let Some(state) = state {
167 state
168 .lock()
169 .await
170 .notify_extensions(ExtensionMessages::CoreMessage(
171 Messages::NotifyLanguageServers { state_id, message },
172 ));
173 }
174 }
175 _ => {
176 let handler = handler.lock().await;
178 handler.send(msg).await;
179 }
180 }
181 }
182}
183
184pub type RPCResult<T> = jsonrpc_core::Result<T>;
185
186#[rpc]
188pub trait RpcMethods {
189 #[rpc(name = "get_state_data_by_id")]
190 fn get_state_by_id(
191 &self,
192 state_id: u8,
193 token: String,
194 ) -> BoxFuture<RPCResult<Result<Option<StateData>, Errors>>>;
195
196 #[rpc(name = "set_state_data_by_id")]
197 fn set_state_by_id(
198 &self,
199 state_id: u8,
200 state: StateData,
201 token: String,
202 ) -> BoxFuture<RPCResult<Result<(), Errors>>>;
203
204 #[rpc(name = "read_file_by_path")]
205 fn read_file_by_path(
206 &self,
207 path: String,
208 filesystem_name: String,
209 state_id: u8,
210 token: String,
211 ) -> BoxFuture<RPCResult<Result<FileInfo, Errors>>>;
212
213 #[rpc(name = "write_file_by_path")]
214 fn write_file_by_path(
215 &self,
216 path: String,
217 content: String,
218 filesystem_name: String,
219 state_id: u8,
220 token: String,
221 ) -> BoxFuture<RPCResult<Result<(), Errors>>>;
222
223 #[rpc(name = "list_dir_by_path")]
224 fn list_dir_by_path(
225 &self,
226 path: String,
227 filesystem_name: String,
228 state_id: u8,
229 token: String,
230 ) -> BoxFuture<RPCResult<Result<Vec<DirItemInfo>, Errors>>>;
231
232 #[rpc(name = "get_ext_info_by_id")]
233 fn get_ext_info_by_id(
234 &self,
235 extension_id: String,
236 state_id: u8,
237 token: String,
238 ) -> BoxFuture<RPCResult<Result<ManifestInfo, Errors>>>;
239
240 #[rpc(name = "get_ext_list_by_id")]
241 fn get_ext_list_by_id(
242 &self,
243 state_id: u8,
244 token: String,
245 ) -> BoxFuture<RPCResult<Result<Vec<String>, Errors>>>;
246
247 #[rpc(name = "get_all_language_servers")]
248 fn get_all_language_servers(
249 &self,
250 state_id: u8,
251 token: String,
252 ) -> BoxFuture<RPCResult<Result<Vec<LanguageServer>, Errors>>>;
253
254 #[rpc(name = "get_all_language_servers")]
255 fn notify_extension(
256 &self,
257 state_id: u8,
258 token: String,
259 message: ExtensionMessages,
260 ) -> BoxFuture<RPCResult<Result<(), Errors>>>;
261}
262
263async fn verify_state(
264 states: Arc<Mutex<StatesList>>,
265 state_id: u8,
266 token: String,
267) -> Result<Arc<Mutex<State>>, Errors> {
268 let states = states.lock().await;
269 if let Some(state) = states.get_state_by_id(state_id) {
271 let state_g = state.lock().await;
272 if state_g.has_token(&token) {
274 drop(state_g);
275 Ok(state)
276 } else {
277 Err(Errors::BadToken)
278 }
279 } else {
280 Err(Errors::StateNotFound)
281 }
282}
283
284pub struct RpcManager {
286 pub states: Arc<Mutex<StatesList>>,
287}
288
289impl RpcMethods for RpcManager {
291 fn get_state_by_id(
293 &self,
294 state_id: u8,
295 token: String,
296 ) -> BoxFuture<RPCResult<Result<Option<StateData>, Errors>>> {
297 let states = self.states.clone();
298 Box::pin(async move {
299 Ok({
300 let state = verify_state(states, state_id, token).await;
301 if let Ok(state) = state {
302 let state = state.lock().await;
303 Ok(Some(state.data.clone()))
304 } else {
305 Err(state.unwrap_err())
306 }
307 })
308 })
309 }
310
311 fn set_state_by_id(
313 &self,
314 state_id: u8,
315 new_state_data: StateData,
316 token: String,
317 ) -> BoxFuture<RPCResult<Result<(), Errors>>> {
318 let states = self.states.clone();
319 Box::pin(async move {
320 Ok({
321 let state = verify_state(states, state_id, token).await;
322
323 if let Ok(state) = state {
324 let mut state = state.lock().await;
325
326 tracing::info!("Updated state by id <{}>", state.data.id);
327 state.update(new_state_data).await;
328
329 Ok(())
330 } else {
331 Err(state.unwrap_err())
332 }
333 })
334 })
335 }
336
337 fn read_file_by_path(
340 &self,
341 path: String,
342 filesystem_name: String,
343 state_id: u8,
344 token: String,
345 ) -> BoxFuture<RPCResult<Result<FileInfo, Errors>>> {
346 let states = self.states.clone();
347 Box::pin(async move {
348 Ok({
349 let state = verify_state(states, state_id, token).await;
350
351 if let Ok(state) = state {
352 let state = state.lock().await;
353
354 if let Some(filesystem) = state.get_fs_by_name(&filesystem_name) {
355 let filesystem = filesystem.lock().await;
356 let result = filesystem.read_file_by_path(&path);
357 let result = result.await;
358
359 state.notify_extensions(ExtensionMessages::ReadFile(
360 state_id,
361 filesystem_name,
362 result.clone(),
363 ));
364
365 result
366 } else {
367 Err(Errors::Fs(FilesystemErrors::FilesystemNotFound))
368 }
369 } else {
370 Err(state.unwrap_err())
371 }
372 })
373 })
374 }
375
376 fn write_file_by_path(
378 &self,
379 path: String,
380 content: String,
381 filesystem_name: String,
382 state_id: u8,
383 token: String,
384 ) -> BoxFuture<RPCResult<Result<(), Errors>>> {
385 let states = self.states.clone();
386
387 Box::pin(async move {
388 Ok({
389 let state = verify_state(states, state_id, token).await;
390
391 if let Ok(state) = state {
392 let state = state.lock().await;
393
394 if let Some(filesystem) = state.get_fs_by_name(&filesystem_name) {
395 let filesystem = filesystem.lock().await;
396 let result = filesystem.write_file_by_path(&path, &content);
397 let result = result.await;
398
399 state.notify_extensions(ExtensionMessages::WriteFile(
400 state_id,
401 filesystem_name,
402 content,
403 result.clone(),
404 ));
405
406 result
407 } else {
408 Err(Errors::Fs(FilesystemErrors::FilesystemNotFound))
409 }
410 } else {
411 Err(state.unwrap_err())
412 }
413 })
414 })
415 }
416
417 fn list_dir_by_path(
420 &self,
421 path: String,
422 filesystem_name: String,
423 state_id: u8,
424 token: String,
425 ) -> BoxFuture<RPCResult<Result<Vec<DirItemInfo>, Errors>>> {
426 let states = self.states.clone();
427
428 Box::pin(async move {
429 Ok({
430 let state = verify_state(states, state_id, token).await;
431
432 if let Ok(state) = state {
433 let state = state.lock().await;
434
435 if let Some(filesystem) = state.get_fs_by_name(&filesystem_name) {
436 let filesystem = filesystem.lock().await;
437 let result = filesystem.list_dir_by_path(&path);
438 let result = result.await;
439
440 state.notify_extensions(ExtensionMessages::ListDir(
441 state_id,
442 filesystem_name,
443 path,
444 result.clone(),
445 ));
446
447 result
448 } else {
449 Err(Errors::Fs(FilesystemErrors::FilesystemNotFound))
450 }
451 } else {
452 Err(state.unwrap_err())
453 }
454 })
455 })
456 }
457
458 fn get_ext_info_by_id(
460 &self,
461 extension_id: String,
462 state_id: u8,
463 token: String,
464 ) -> BoxFuture<RPCResult<Result<ManifestInfo, Errors>>> {
465 let states = self.states.clone();
466
467 Box::pin(async move {
468 Ok({
469 let state = verify_state(states, state_id, token).await;
470
471 if let Ok(state) = state {
472 let state = state.lock().await;
473
474 state.get_ext_info_by_id(&extension_id)
475 } else {
476 Err(state.unwrap_err())
477 }
478 })
479 })
480 }
481 fn get_ext_list_by_id(
483 &self,
484 state_id: u8,
485 token: String,
486 ) -> BoxFuture<RPCResult<Result<Vec<String>, Errors>>> {
487 let states = self.states.clone();
488 Box::pin(async move {
489 Ok({
490 let state = verify_state(states, state_id, token).await;
491
492 if let Ok(state) = state {
493 let state = state.lock().await;
494
495 Ok(state.get_ext_list_by_id())
496 } else {
497 Err(state.unwrap_err())
498 }
499 })
500 })
501 }
502
503 fn get_all_language_servers(
505 &self,
506 state_id: u8,
507 token: String,
508 ) -> BoxFuture<RPCResult<Result<Vec<LanguageServer>, Errors>>> {
509 let states = self.states.clone();
510 Box::pin(async move {
511 Ok({
512 let state = verify_state(states, state_id, token).await;
513
514 if let Ok(state) = state {
515 let state = state.lock().await;
516
517 Ok(state.get_all_language_servers().await)
518 } else {
519 Err(state.unwrap_err())
520 }
521 })
522 })
523 }
524
525 fn notify_extension(
526 &self,
527 state_id: u8,
528 token: String,
529 message: ExtensionMessages,
530 ) -> BoxFuture<RPCResult<Result<(), Errors>>> {
531 let states = self.states.clone();
532 Box::pin(async move {
533 Ok({
534 let state = verify_state(states, state_id, token).await;
535
536 if let Ok(state) = state {
537 let state = state.lock().await;
538
539 state.notify_extensions(message);
540
541 Ok(())
542 } else {
543 Err(state.unwrap_err())
544 }
545 })
546 })
547 }
548}