@@ -0,0 +1,370 @@
1+//! An implementation of the JSONRPC 2.0 spec types
3+// Upstream implementation: https://github.com/paritytech/jsonrpc/tree/38af3c9439aa75481805edf6c05c6622a5ab1e70/core/src/types
4+// Changes from upstream:
5+// * unused functions (almost all non-trait-implementation functions) have been removed
6+// * `#[serde(deny_unknown_fields)]` annotations have been removed on response types
7+// for compatibility with non-strict language server implementations like Ruby Sorbet
8+// (see https://github.com/helix-editor/helix/issues/2786)
9+// * some variable names have been lengthened for readability
11+use serde::de::{self, DeserializeOwned, Visitor};
12+use serde::{Deserialize, Serialize};
13+use serde_json::Value;
15+// https://www.jsonrpc.org/specification#error_object
16+#[derive(Debug, PartialEq, Clone)]
27+ pub fn code(&self) -> i64 {
29+ ErrorCode::ParseError => -32700,
30+ ErrorCode::InvalidRequest => -32600,
31+ ErrorCode::MethodNotFound => -32601,
32+ ErrorCode::InvalidParams => -32602,
33+ ErrorCode::InternalError => -32603,
34+ ErrorCode::ServerError(code) => code,
39+impl From<i64> for ErrorCode {
40+ fn from(code: i64) -> Self {
42+ -32700 => ErrorCode::ParseError,
43+ -32600 => ErrorCode::InvalidRequest,
44+ -32601 => ErrorCode::MethodNotFound,
45+ -32602 => ErrorCode::InvalidParams,
46+ -32603 => ErrorCode::InternalError,
47+ code => ErrorCode::ServerError(code),
52+impl<'de> Deserialize<'de> for ErrorCode {
53+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
55+ D: serde::Deserializer<'de>,
57+ let code: i64 = Deserialize::deserialize(deserializer)?;
58+ Ok(ErrorCode::from(code))
62+impl Serialize for ErrorCode {
63+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65+ S: serde::Serializer,
67+ serializer.serialize_i64(self.code())
71+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
75+ #[serde(skip_serializing_if = "Option::is_none")]
76+ pub data: Option<Value>,
80+ pub fn invalid_params<M>(message: M) -> Self
85+ code: ErrorCode::InvalidParams,
86+ message: message.into(),
92+impl std::fmt::Display for Error {
93+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94+ write!(f, "{:?}: {}", self.code, self.message)
98+impl std::error::Error for Error {}
100+// https://www.jsonrpc.org/specification#request_object
103+#[derive(Debug, PartialEq, Clone, Hash, Eq, Deserialize, Serialize)]
112+#[derive(Debug, PartialEq, Clone, Copy, Hash, Eq)]
117+impl Serialize for Version {
118+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
120+ S: serde::Serializer,
123+ Version::V2 => serializer.serialize_str("2.0"),
128+struct VersionVisitor;
130+impl<'v> Visitor<'v> for VersionVisitor {
131+ type Value = Version;
133+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
134+ formatter.write_str("a string")
136+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
141+ "2.0" => Ok(Version::V2),
142+ _ => Err(de::Error::custom("invalid version")),
147+impl<'de> Deserialize<'de> for Version {
148+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
150+ D: serde::Deserializer<'de>,
152+ deserializer.deserialize_identifier(VersionVisitor)
156+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
161+ Map(serde_json::Map<String, Value>),
165+ pub fn parse<D>(self) -> Result<D, Error>
167+ D: DeserializeOwned,
169+ let value: Value = self.into();
170+ serde_json::from_value(value)
171+ .map_err(|err| Error::invalid_params(format!("Invalid params: {}.", err)))
175+impl From<Params> for Value {
176+ fn from(params: Params) -> Value {
178+ Params::Array(vec) => Value::Array(vec),
179+ Params::Map(map) => Value::Object(map),
180+ Params::None => Value::Null,
185+#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
186+#[serde(deny_unknown_fields)]
187+pub struct MethodCall {
188+ pub jsonrpc: Option<Version>,
190+ #[serde(default = "default_params")]
195+#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
196+#[serde(deny_unknown_fields)]
197+pub struct Notification {
198+ pub jsonrpc: Option<Version>,
200+ #[serde(default = "default_params")]
204+#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
205+#[serde(deny_unknown_fields)]
208+ MethodCall(MethodCall),
209+ Notification(Notification),
211+ // We can attempt to salvage the id out of the invalid request
212+ // for better debugging
213+ #[serde(default = "default_id")]
218+fn default_params() -> Params {
222+fn default_id() -> Id {
226+impl From<MethodCall> for Call {
227+ fn from(method_call: MethodCall) -> Self {
228+ Call::MethodCall(method_call)
232+impl From<Notification> for Call {
233+ fn from(notification: Notification) -> Self {
234+ Call::Notification(notification)
238+#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
239+#[serde(deny_unknown_fields)]
246+// https://www.jsonrpc.org/specification#response_object
248+#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
250+ #[serde(skip_serializing_if = "Option::is_none")]
251+ pub jsonrpc: Option<Version>,
256+#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
258+ #[serde(skip_serializing_if = "Option::is_none")]
259+ pub jsonrpc: Option<Version>,
264+// Note that failure comes first because we're not using
265+// #[serde(deny_unknown_field)]: we want a request that contains
266+// both `result` and `error` to be a `Failure`.
267+#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
274+impl From<Output> for Result<Value, Error> {
275+ fn from(output: Output) -> Self {
277+ Output::Success(success) => Ok(success.result),
278+ Output::Failure(failure) => Err(failure.error),
283+#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
290+impl From<Failure> for Response {
291+ fn from(failure: Failure) -> Self {
292+ Response::Single(Output::Failure(failure))
296+impl From<Success> for Response {
297+ fn from(success: Success) -> Self {
298+ Response::Single(Output::Success(success))
303+fn method_call_serialize() {
306+ let m = MethodCall {
307+ jsonrpc: Some(Version::V2),
308+ method: "update".to_owned(),
309+ params: Params::Array(vec![Value::from(1), Value::from(2)]),
313+ let serialized = serde_json::to_string(&m).unwrap();
316+ r#"{"jsonrpc":"2.0","method":"update","params":[1,2],"id":1}"#
321+fn notification_serialize() {
324+ let n = Notification {
325+ jsonrpc: Some(Version::V2),
326+ method: "update".to_owned(),
327+ params: Params::Array(vec![Value::from(1), Value::from(2)]),
330+ let serialized = serde_json::to_string(&n).unwrap();
333+ r#"{"jsonrpc":"2.0","method":"update","params":[1,2]}"#
338+fn success_output_deserialize() {
341+ let dso = r#"{"jsonrpc":"2.0","result":1,"id":1}"#;
343+ let deserialized: Output = serde_json::from_str(dso).unwrap();
346+ Output::Success(Success {
347+ jsonrpc: Some(Version::V2),
348+ result: Value::from(1),
355+fn success_output_deserialize_with_extra_fields() {
358+ // https://github.com/helix-editor/helix/issues/2786
359+ let dso = r#"{"jsonrpc":"2.0","result":1,"id":1,"requestMethod":"initialize"}"#;
361+ let deserialized: Output = serde_json::from_str(dso).unwrap();
364+ Output::Success(Success {
365+ jsonrpc: Some(Version::V2),
366+ result: Value::from(1),