1mod analysis;
30mod capabilities;
31mod common;
32pub(crate) mod configuration;
33mod lsp;
34mod sparql_operations;
35mod state;
36mod tools;
37
38pub(crate) mod message_handler;
39
40use capabilities::create_capabilities;
41use configuration::Settings;
42use futures::lock::Mutex;
43use log::{error, info};
44use lsp::{
45 ServerInfo,
46 errors::{ErrorCode, LSPError},
47 rpc::{RecoverId, ResponseMessage},
48};
49use message_handler::dispatch;
50use serde::Serialize;
51use state::ServerState;
52use std::{any::type_name, fmt::Debug, rc::Rc};
53use tools::Tools;
54use wasm_bindgen::prelude::wasm_bindgen;
55
56use crate::server::lsp::LspMessage;
57
58#[wasm_bindgen]
59pub struct Server {
60 pub(crate) state: ServerState,
61 pub(crate) settings: Settings,
62 pub(crate) capabilities: lsp::capabilities::ServerCapabilities,
63 pub(crate) client_capabilities: Option<lsp::capabilities::ClientCapabilities>,
64 pub(crate) server_info: ServerInfo,
65 tools: Tools,
66 send_message_closure: Box<dyn Fn(String)>,
67}
68
69impl Server {
70 pub fn new(write_function: impl Fn(String) + 'static) -> Server {
71 let version = env!("CARGO_PKG_VERSION");
72 info!("Started Language Server: Qlue-ls - version: {}", version);
73 Self {
74 state: ServerState::new(),
75 settings: Settings::new(),
76 capabilities: create_capabilities(),
77 client_capabilities: None,
78 server_info: ServerInfo {
79 name: "Qlue-ls".to_string(),
80 version: Some(version.to_string()),
81 },
82 tools: Tools::init(),
83 send_message_closure: Box::new(write_function),
84 }
85 }
86
87 pub(crate) fn bump_request_id(&mut self) -> u32 {
88 self.state.bump_request_id()
89 }
90
91 pub fn get_version(&self) -> String {
92 self.server_info
93 .version
94 .clone()
95 .unwrap_or("not-specified".to_string())
96 }
97
98 fn send_message<T>(&self, message: T) -> Result<(), LSPError>
99 where
100 T: Serialize + LspMessage + Debug,
101 {
102 let message_string = serde_json::to_string(&message).map_err(|error| {
103 LSPError::new(
104 ErrorCode::ParseError,
105 &format!(
106 "Could not deserialize RPC-message \"{}\"\n\n{}",
107 type_name::<T>(),
108 error
109 ),
110 )
111 })?;
112 (self.send_message_closure)(message_string);
113 Ok(())
114 }
115
116 pub(crate) fn shorten_uri(
140 &self,
141 uri: &str,
142 backend_name: Option<&str>,
143 ) -> Option<(String, String, String)> {
144 let converter = backend_name
145 .and_then(|name| self.state.get_converter(name))
146 .or(self.state.get_default_converter())?;
147 let record = converter.find_by_uri(uri).ok()?;
148 let curie = converter.compress(uri).ok()?;
149 Some((record.prefix.clone(), record.uri_prefix.clone(), curie))
150 }
151}
152
153async fn handle_error(server_rc: Rc<Mutex<Server>>, message: &str, error: LSPError) {
154 log::error!(
155 "Error occurred while handling message:\n\"{}\"\n\n{:?}\n{}",
156 message,
157 error.code,
158 error.message
159 );
160 if let Ok(id) = serde_json::from_str::<RecoverId>(message).map(|msg| msg.id)
161 && let Err(error) = server_rc
162 .lock()
163 .await
164 .send_message(ResponseMessage::error(&id, error))
165 {
166 error!(
167 "CRITICAL: could not serialize error message (this very bad):\n{:?}",
168 error
169 )
170 }
171}
172
173pub async fn handle_message(server_rc: Rc<Mutex<Server>>, message: String) {
174 if let Err(err) = dispatch(server_rc.clone(), &message).await {
175 handle_error(server_rc.clone(), &message, err).await;
176 }
177}