sync_lsp/window/
show_message_request.rs

1//! implements the `window/showMessageRequest` request.
2//!
3//! # Usage
4//! This request may be used to query the user for a choice.
5//! The result can be retrieved using [`Server::on_show_message_response`] and therefore
6//! [`Connection::show_message_request`] won't block the current thread.
7
8use std::collections::HashMap;
9use std::mem::replace;
10use serde::{Serialize, Deserialize};
11use crate::{Connection, Server, TypeProvider};
12use crate::connection::{RpcConnection, Callback};
13
14use super::MessageType;
15
16pub(super) struct ShowMessageRequest<T: TypeProvider> {
17    callback: Callback<Server<T>>
18}
19
20/// This Item is beeing sent along every show message request.
21#[derive(Serialize, Deserialize, Debug)]
22#[serde(bound = "")]
23pub struct MessageActionItem<T: Default> {
24    /// The title of the message action which will be shown to the user.
25    pub title: String,
26    /// This field is preserved and will be sent back in the response.
27    /// It's type can be specified using the [`TypeProvider`] trait.
28    #[serde(skip)]
29    #[serde(default)]
30    pub data: T
31}
32
33#[derive(Serialize)]
34#[serde(bound = "")]
35struct ShowMessageRequestParams<T: Default> {
36    #[serde(rename = "type")]
37    r#type: MessageType,
38    message: String,
39    #[serde(skip_serializing_if = "Vec::is_empty")]
40    actions: Vec<MessageActionItem<T>>
41}
42
43impl<T: TypeProvider> Connection<T> {
44
45    /// This request will [trigger a query](self) to the user.
46    /// 
47    /// # Arguments
48    /// * `r#type` - The type of message to show.
49    /// * `message` - The message to show.
50    /// * `actions` - The actions to show.
51    /// * `result` - A boolean indicating whether the request was sent.
52    
53    pub fn show_message_request(&mut self, r#type: MessageType, message: String, mut actions: Vec<MessageActionItem<T::ShowMessageRequestData>>) -> bool {
54        self.request(
55            ShowMessageRequest::<T>::METHOD,
56            {
57                let mut hashmap = HashMap::new();
58                for action in actions.iter_mut() {
59                    let data = replace(&mut action.data, Default::default());
60                    hashmap.insert(action.title.clone(), data);
61                }
62                hashmap
63            },
64            ShowMessageRequestParams {
65                r#type,
66                message,
67                actions
68            }
69        )
70    }
71}
72
73impl<T: TypeProvider> Server<T> {
74
75    /// Set the response handler for [showing a message request](self)
76    ///
77    /// # Argument
78    /// * `callback` - A callback which is called with the following parameters if the result of a query is received:
79    ///     * The server instance receiving the response.
80    ///     * A tag of type [`TypeProvider::ShowMessageRequestData`] that was passed to the request.
81    
82    pub fn on_show_message_response(&mut self, callback: fn(&mut Server<T>, MessageActionItem<T::ShowMessageRequestData>)) {
83        self.window.show_message_request.callback = Callback::response(move |connection, mut tag: HashMap<String, T::ShowMessageRequestData>, params: Option<MessageActionItem<T::ShowMessageRequestData>>| {
84            if let Some(mut action) = params {
85                action.data = tag.remove(action.title.as_str()).unwrap_or_default();
86                callback(connection, action)
87            }
88        })
89    }
90}
91
92impl<T: TypeProvider> Default for ShowMessageRequest<T> {
93    fn default() -> Self {
94        Self {
95            callback: Callback::response(|_, _: HashMap<String, T::ShowMessageRequestData>, _: Option<MessageActionItem<T::ShowMessageRequestData>>| {})
96        }
97    }
98}
99
100impl<T: TypeProvider> ShowMessageRequest<T> {
101    pub(super) const METHOD: &'static str = "window/showMessageRequest";
102
103    pub(crate) fn callback(&self) -> Callback<Server<T>> {
104        self.callback.clone()
105    }
106}