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.
pull/5485/head
Michael Davis 2 years ago committed by GitHub
parent 2d601d6a59
commit 22298434f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -170,6 +170,10 @@ impl Params {
serde_json::from_value(value) serde_json::from_value(value)
.map_err(|err| Error::invalid_params(format!("Invalid params: {}.", err))) .map_err(|err| Error::invalid_params(format!("Invalid params: {}.", err)))
} }
pub fn is_none(&self) -> bool {
self == &Params::None
}
} }
impl From<Params> for Value { impl From<Params> for Value {
@ -187,7 +191,7 @@ impl From<Params> for Value {
pub struct MethodCall { pub struct MethodCall {
pub jsonrpc: Option<Version>, pub jsonrpc: Option<Version>,
pub method: String, pub method: String,
#[serde(default = "default_params")] #[serde(default = "default_params", skip_serializing_if = "Params::is_none")]
pub params: Params, pub params: Params,
pub id: Id, pub id: Id,
} }
@ -197,7 +201,7 @@ pub struct MethodCall {
pub struct Notification { pub struct Notification {
pub jsonrpc: Option<Version>, pub jsonrpc: Option<Version>,
pub method: String, pub method: String,
#[serde(default = "default_params")] #[serde(default = "default_params", skip_serializing_if = "Params::is_none")]
pub params: Params, pub params: Params,
} }
@ -334,6 +338,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] #[test]
fn success_output_deserialize() { fn success_output_deserialize() {
use serde_json; use serde_json;

Loading…
Cancel
Save