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::definition::get_language_id_by_uri; use crate::server::Backend; use crate::sources::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; future::ready(do_fast(path)) } } 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(path: String) -> Result { info!("parse hdl path: {:?}", 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 = parse( &text, &uri, &None, &includes ); if let Some(syntax_tree) = parse_result { let hdlparam = make_fast_from_syntaxtree(&syntax_tree, &path_buf); return Ok(hdlparam); } 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 UpdateFastNotification { pub fast: FastHdlparam } impl Notification for UpdateFastNotification { const METHOD: &'static str = "update/fast"; type Params = Self; } pub fn update_fast_to_client(backend: Arc>, fast: FastHdlparam) { let backend = backend.unwrap(); let params = UpdateFastNotification { fast }; backend.client.send_notification::(params); }