use std::{fs, future}; use std::path::PathBuf; use std::sync::Arc; use log::info; use notification::Notification; use ropey::Rope; use serde::{Deserialize, Serialize}; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::*; use crate::core::fast_hdlparam::FastHdlparam; use crate::core::sv_parser::make_fast_from_syntaxtree; use crate::utils::*; use crate::server::{Backend, GLOBAL_BACKEND}; use crate::sources::recovery_sv_parse; #[derive(Clone)] pub struct CustomRequest; impl <'a>tower_lsp::jsonrpc::Method<&'a Arc, (), Result> for CustomRequest { type Future = future::Ready>; fn invoke(&self, _server: &'a Arc, _params: ()) -> Self::Future { future::ready(custom_request()) } } pub fn custom_request() -> Result { Ok(123) } #[derive(Deserialize, Serialize, Debug)] pub struct CustomParamRequestParams { param: String, } #[derive(Clone)] pub struct CustomParamRequest; impl <'a>tower_lsp::jsonrpc::Method<&'a Arc, (CustomParamRequestParams, ), Result> for CustomParamRequest { type Future = future::Ready>; fn invoke(&self, _server: &'a Arc, _params: (CustomParamRequestParams, )) -> Self::Future { future::ready(custom_param_request(_params.0.param)) } } pub fn custom_param_request(param: String) -> Result { info!("receive param: {:?}", param); Ok(123) } #[derive(Deserialize, Serialize, Debug)] pub struct DoFastApiRequestParams { path: String, } #[derive(Clone)] pub struct DoFastApi; impl <'a>tower_lsp::jsonrpc::Method<&'a Arc, (DoFastApiRequestParams, ), Result> for DoFastApi { type Future = future::Ready>; fn invoke(&self, _server: &'a Arc, _params: (DoFastApiRequestParams, )) -> Self::Future { let request_param = _params.0; let path = request_param.path; let hdlparam = do_fast(path, _server); future::ready(hdlparam) } } fn make_textdocumenitem_from_path(path_buf: &PathBuf) -> Option { if let Ok(url) = Url::from_file_path(path_buf) { if let Ok(text) = fs::read_to_string(path_buf) { let language_id = get_language_id_by_uri(&url); return Some(TextDocumentItem::new(url, language_id, -1, text)); } } None } /// 前端交互接口: do_fast,输入文件路径,计算出对应的 fast 结构 pub fn do_fast<'a>(path: String, _server: &Arc) -> Result { info!("parse fast {}", path); let path_buf = PathBuf::from(&path); let doc = match make_textdocumenitem_from_path(&path_buf) { Some(doc) => doc, None => { let api_error = tower_lsp::jsonrpc::Error { code: tower_lsp::jsonrpc::ErrorCode::InvalidParams, message: std::borrow::Cow::Owned(format!("cannot make doc from path : {path}")), data: None }; return Err(api_error); } }; let uri = doc.uri; let text = Rope::from(doc.text); // fast 解析不需要 include let includes: Vec = Vec::new(); let parse_result = recovery_sv_parse( &text, &uri, &None, &includes ); if let Some(syntax_tree) = parse_result { if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) { let hdl_param = _server.server.srcs.hdl_param.clone(); hdl_param.update_fast(path.to_string(), fast.clone()); return Ok(fast); } } let api_error = tower_lsp::jsonrpc::Error { code: tower_lsp::jsonrpc::ErrorCode::ParseError, message: std::borrow::Cow::Owned("message".to_string()), data: None }; Err(api_error) } // 下面是服务端发送给客户端的 #[derive(Serialize, Deserialize)] pub struct StringNotification { pub content: String } impl Notification for StringNotification { const METHOD: &'static str = "update/string"; type Params = Self; } #[derive(Serialize, Deserialize)] pub struct UpdateFastNotification { pub fast: FastHdlparam, pub path: String } impl Notification for UpdateFastNotification { const METHOD: &'static str = "update/fast"; type Params = Self; } #[allow(unused)] pub async fn update_fast_to_client(fast: FastHdlparam, path: &PathBuf) { // info!("send fast to foreend {:?}", fast); info!("send fast to foreend"); let backend = GLOBAL_BACKEND.get().unwrap(); let path = path.to_str().unwrap_or("").to_string(); let params = UpdateFastNotification { fast, path }; info!("backend client: {:?}", backend.client); backend.client.send_notification::(params).await; }