sync_lsp/workspace/
apply_edit.rs

1//! Implementation of the `workspace/applyEdit` request.
2//! 
3//! # Usage
4//! Many `Command` implementations will want to apply edits to the workspace and 
5//! may do so by using this request via [`Connection::apply_edit`].
6//! The server shouldn't assume that the edit will be immediately applied.
7//! Instead, the [`Server::on_apply_edit_response`] callback should be used to check whether
8//! the edit was applied or not.
9
10use std::collections::HashMap;
11use crate::text_document::{DocumentUri, TextEdit};
12use serde::{Serialize, Deserialize};
13use crate::connection::{RpcConnection, Callback};
14use crate::{Server, Connection, TypeProvider};
15
16/// A workspace edit represents changes to many resources managed in the workspace.
17#[derive(Serialize, Debug, Default)]
18pub struct WorkspaceEdit {
19    /// Holds changes to existing resources.
20    pub changes: HashMap<DocumentUri, Vec<TextEdit>>
21}
22
23pub(super) struct ApplyEdit<T: TypeProvider> {
24    callback: Callback<Server<T>>
25}
26
27#[derive(Serialize)]
28struct ApplyWorkspaceEditParams {
29    edit: WorkspaceEdit
30}
31
32/// This response is sent when the [`Connection::apply_edit`] request has been completed
33/// and the edit has been applied.
34#[derive(Deserialize, Debug, Default)]
35pub struct ApplyWorkspaceEditResponse {
36    /// Indicates whether the edit was applied or not.
37    pub applied: bool
38}
39
40impl<T: TypeProvider> Connection<T> {
41
42    /// Request the [application of a workspace edit](self)
43    ///
44    /// # Arguments
45    /// * `tag` - A tag of type [`TypeProvider::ApplyEditData`] preserved throughout the request.
46    /// * `edit` - The workspace edit to apply.
47    /// * `result` - A boolean indicating whether the request was sent.
48    
49    pub fn apply_edit(&mut self, tag: T::ApplyEditData, edit: WorkspaceEdit) -> bool {
50        self.request(
51            ApplyEdit::<T>::METHOD,
52            tag,
53            ApplyWorkspaceEditParams { edit }
54        )
55    }
56}
57
58impl<T: TypeProvider> Server<T> {
59    
60    /// Set the response handler for [applying a workspace edit](self)
61    ///
62    /// # Argument
63    /// * `callback` - A callback which is called with the following parameters as soon as a response from [`Connection::apply_edit`] is received:
64    ///     * The server instance receiving the response.
65    ///     * A tag of type [`TypeProvider::ApplyEditData`] that was passed to the request.
66    ///     * The response data of the client.
67
68    pub fn on_apply_edit_response(&mut self, callback: fn(&mut Server<T>, T::ApplyEditData, ApplyWorkspaceEditResponse)) {
69        self.workspace.apply_edit.callback = Callback::response(callback);
70    }
71}
72
73impl<T: TypeProvider> Default for ApplyEdit<T> {
74    fn default() -> Self {
75        Self {
76            callback: Callback::response(|_, _: T::ApplyEditData, _: ApplyWorkspaceEditResponse| ())
77        }
78    }
79}
80
81impl<T: TypeProvider> ApplyEdit<T> {
82    pub(super) const METHOD: &'static str = "workspace/applyEdit";
83
84    pub(crate) fn callback(&self) -> Callback<Server<T>> {
85        self.callback.clone()
86    }
87}