summaryrefslogtreecommitdiff
path: root/support/texlab/src/client.rs
blob: 72f2ac9eba4075591d4bc56b04415a60ec14f81b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::sync::Mutex;

use anyhow::{anyhow, Result};
use crossbeam_channel::{Receiver, Sender};
use lsp_server::{Message, ResponseError};
use serde::{de::DeserializeOwned, Serialize};

use crate::req_queue::{OutgoingData, ReqQueue};

pub fn send_notification<N>(lsp_sender: &Sender<Message>, params: N::Params) -> Result<()>
where
    N: lsp_types::notification::Notification,
    N::Params: Serialize,
{
    lsp_sender.send(lsp_server::Notification::new(N::METHOD.to_string(), params).into())?;
    Ok(())
}

pub fn send_request<R>(
    req_queue: &Mutex<ReqQueue>,
    lsp_sender: &Sender<Message>,
    params: R::Params,
) -> Result<R::Result>
where
    R: lsp_types::request::Request,
    R::Params: Serialize,
    R::Result: DeserializeOwned,
{
    let receiver = register_outgoing_request::<R>(req_queue, lsp_sender, params)?;
    let params = receiver.recv()?.map_err(|err| anyhow!(err.message))?;
    let result = serde_json::from_value(params)?;
    Ok(result)
}

fn register_outgoing_request<R>(
    req_queue: &Mutex<ReqQueue>,
    lsp_sender: &Sender<Message>,
    params: R::Params,
) -> Result<Receiver<Result<serde_json::Value, ResponseError>>>
where
    R: lsp_types::request::Request,
    R::Params: Serialize,
    R::Result: DeserializeOwned,
{
    let mut req_queue = req_queue.lock().unwrap();
    let (sender, receiver) = crossbeam_channel::bounded(1);
    let method = R::METHOD.to_string();
    let data = OutgoingData { sender };
    let req = req_queue.outgoing.register(method, params, data);
    drop(req_queue);
    lsp_sender.send(req.into())?;
    Ok(receiver)
}