qlue-ls 2.6.1

A language server for SPARQL
Documentation
mod documentation;
mod iri;

use std::rc::Rc;

use futures::lock::Mutex;
use ll_sparql_parser::{TokenAtOffset, syntax_kind::SyntaxKind};

use tracing::instrument;

use crate::server::{
    Server,
    lsp::{
        HoverRequest, HoverResponse,
        errors::{ErrorCode, LSPError},
    },
};

#[instrument(skip_all, fields(id = %request.get_id(), uri = %request.get_document_uri()))]
pub(super) async fn handle_hover_request(
    server_rc: Rc<Mutex<Server>>,
    request: HoverRequest,
) -> Result<(), LSPError> {
    let (root, document_text) = {
        let server = server_rc.lock().await;
        let document = server.state.get_document(request.get_document_uri())?;
        (
            server
                .state
                .get_cached_parse_tree(request.get_document_uri())?
                .tree,
            document.text.clone(),
        )
    };
    let mut hover_response = HoverResponse::new(request.get_id());
    let offset = request
        .get_position()
        .byte_index(&document_text)
        .ok_or_else(|| {
            LSPError::new(
                ErrorCode::InvalidParams,
                "The hover position is not inside the text document",
            )
        })?;
    if let TokenAtOffset::Single(token) = root.token_at_offset(offset)
        && let Some(content) = match token.kind() {
            SyntaxKind::PNAME_LN | SyntaxKind::PNAME_NS | SyntaxKind::IRIREF => {
                iri::hover(server_rc.clone(), root, token).await?
            }
            other => documentation::get_docstring_for_kind(other),
        }
    {
        hover_response.set_markdown_content(content.to_string());
    }
    server_rc.lock().await.send_message(hover_response)
}