aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Davis2023-01-10 09:31:41 +0000
committerGitHub2023-01-10 09:31:41 +0000
commit22298434f10e203bc1adb8eebfdfbfbff05db977 (patch)
treeae94944949a012b41bed93ad10d5be55af66459b
parent2d601d6a59dd46cccfcbda625387f21981e0a8a5 (diff)
jsonrpc: Skip serializing params if params are None (#5471)
The JSONRPC spec says: > If present, parameters for the rpc call MUST be provided as a > Structured value https://www.jsonrpc.org/specification#parameter_structures (Where a "Structured value" is elsewhere defined as either a map or array.) This change skips the serialization of the `params` field for JSONRPC method calls and notifications if the `params` field is the `None` variant. This fixes compatibility with LSP servers which adhere closely to that part of the spec: `ocamllsp` in the wild.
-rw-r--r--helix-lsp/src/jsonrpc.rs35
1 files changed, 33 insertions, 2 deletions
diff --git a/helix-lsp/src/jsonrpc.rs b/helix-lsp/src/jsonrpc.rs
index 75ac9309..69d02707 100644
--- a/helix-lsp/src/jsonrpc.rs
+++ b/helix-lsp/src/jsonrpc.rs
@@ -170,6 +170,10 @@ impl Params {
serde_json::from_value(value)
.map_err(|err| Error::invalid_params(format!("Invalid params: {}.", err)))
}
+
+ pub fn is_none(&self) -> bool {
+ self == &Params::None
+ }
}
impl From<Params> for Value {
@@ -187,7 +191,7 @@ impl From<Params> for Value {
pub struct MethodCall {
pub jsonrpc: Option<Version>,
pub method: String,
- #[serde(default = "default_params")]
+ #[serde(default = "default_params", skip_serializing_if = "Params::is_none")]
pub params: Params,
pub id: Id,
}
@@ -197,7 +201,7 @@ pub struct MethodCall {
pub struct Notification {
pub jsonrpc: Option<Version>,
pub method: String,
- #[serde(default = "default_params")]
+ #[serde(default = "default_params", skip_serializing_if = "Params::is_none")]
pub params: Params,
}
@@ -335,6 +339,33 @@ fn notification_serialize() {
}
#[test]
+fn serialize_skip_none_params() {
+ use serde_json;
+
+ let m = MethodCall {
+ jsonrpc: Some(Version::V2),
+ method: "shutdown".to_owned(),
+ params: Params::None,
+ id: Id::Num(1),
+ };
+
+ let serialized = serde_json::to_string(&m).unwrap();
+ assert_eq!(
+ serialized,
+ r#"{"jsonrpc":"2.0","method":"shutdown","id":1}"#
+ );
+
+ let n = Notification {
+ jsonrpc: Some(Version::V2),
+ method: "exit".to_owned(),
+ params: Params::None,
+ };
+
+ let serialized = serde_json::to_string(&n).unwrap();
+ assert_eq!(serialized, r#"{"jsonrpc":"2.0","method":"exit"}"#);
+}
+
+#[test]
fn success_output_deserialize() {
use serde_json;