diff --git a/Cargo.lock b/Cargo.lock index e0f051908cb4..8d9304dfaf31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1455,7 +1455,7 @@ dependencies = [ [[package]] name = "lsp-server" -version = "0.8.0" +version = "0.9.0" dependencies = [ "anyhow", "crossbeam-channel", diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml index 285f58e7fca5..06a452984fc3 100644 --- a/lib/lsp-server/Cargo.toml +++ b/lib/lsp-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lsp-server" -version = "0.8.0" +version = "0.9.0" description = "Generic LSP server scaffold." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" diff --git a/lib/lsp-server/examples/minimal_lsp.rs b/lib/lsp-server/examples/minimal_lsp.rs index 3558a6c3bfdb..eb0832745560 100644 --- a/lib/lsp-server/examples/minimal_lsp.rs +++ b/lib/lsp-server/examples/minimal_lsp.rs @@ -82,7 +82,9 @@ use toolchain::command; // clippy-approved wrapper #[allow(clippy::print_stderr, clippy::disallowed_types, clippy::disallowed_methods)] use anyhow::{Context, Result, anyhow, bail}; -use lsp_server::{Connection, Message, Request as ServerRequest, RequestId, Response}; +use lsp_server::{ + Connection, Message, Request as ServerRequest, RequestId, Response, ResponseKind, +}; // ===================================================================== // main @@ -304,7 +306,8 @@ fn full_range(text: &str) -> Range { } fn send_ok(conn: &Connection, id: RequestId, result: &T) -> Result<()> { - let resp = Response { id, result: Some(serde_json::to_value(result)?), error: None }; + let resp = + Response { id, response_kind: ResponseKind::Ok { result: serde_json::to_value(result)? } }; conn.sender.send(Message::Response(resp))?; Ok(()) } @@ -317,12 +320,9 @@ fn send_err( ) -> Result<()> { let resp = Response { id, - result: None, - error: Some(lsp_server::ResponseError { - code: code as i32, - message: msg.into(), - data: None, - }), + response_kind: ResponseKind::Err { + error: lsp_server::ResponseError { code: code as i32, message: msg.into(), data: None }, + }, }; conn.sender.send(Message::Response(resp))?; Ok(()) diff --git a/lib/lsp-server/src/lib.rs b/lib/lsp-server/src/lib.rs index 3f29c39c49f0..5eaedbb6429d 100644 --- a/lib/lsp-server/src/lib.rs +++ b/lib/lsp-server/src/lib.rs @@ -22,7 +22,9 @@ use crossbeam_channel::{Receiver, RecvError, RecvTimeoutError, Sender}; pub use crate::{ error::{ExtractError, ProtocolError}, - msg::{ErrorCode, Message, Notification, Request, RequestId, Response, ResponseError}, + msg::{ + ErrorCode, Message, Notification, Request, RequestId, Response, ResponseError, ResponseKind, + }, req_queue::{Incoming, Outgoing, ReqQueue}, stdio::IoThreads, }; diff --git a/lib/lsp-server/src/msg.rs b/lib/lsp-server/src/msg.rs index 305008e69ae1..64e2ba750904 100644 --- a/lib/lsp-server/src/msg.rs +++ b/lib/lsp-server/src/msg.rs @@ -84,10 +84,15 @@ pub struct Response { // request id. We fail deserialization in that case, so we just // make this field mandatory. pub id: RequestId, - #[serde(skip_serializing_if = "Option::is_none", default)] - pub result: Option, - #[serde(skip_serializing_if = "Option::is_none", default)] - pub error: Option, + #[serde(flatten)] + pub response_kind: ResponseKind, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum ResponseKind { + Ok { result: serde_json::Value }, + Err { error: ResponseError }, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -198,11 +203,14 @@ impl Message { impl Response { pub fn new_ok(id: RequestId, result: R) -> Response { - Response { id, result: Some(serde_json::to_value(result).unwrap()), error: None } + Response { + id, + response_kind: ResponseKind::Ok { result: serde_json::to_value(result).unwrap() }, + } } pub fn new_err(id: RequestId, code: i32, message: String) -> Response { let error = ResponseError { code, message, data: None }; - Response { id, result: None, error: Some(error) } + Response { id, response_kind: ResponseKind::Err { error } } } } diff --git a/lib/lsp-server/src/req_queue.rs b/lib/lsp-server/src/req_queue.rs index 84748bbca8d7..0c39a1dc7a1f 100644 --- a/lib/lsp-server/src/req_queue.rs +++ b/lib/lsp-server/src/req_queue.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::{ErrorCode, Request, RequestId, Response, ResponseError}; +use crate::{ErrorCode, Request, RequestId, Response, ResponseError, msg::ResponseKind}; /// Manages the set of pending requests, both incoming and outgoing. #[derive(Debug)] @@ -47,7 +47,7 @@ impl Incoming { message: "canceled by client".to_owned(), data: None, }; - Some(Response { id, result: None, error: Some(error) }) + Some(Response { id, response_kind: ResponseKind::Err { error } }) } pub fn complete(&mut self, id: &RequestId) -> Option {