1pub(crate) use self::error::not_initialized_error;
4pub use self::error::{Error, ErrorCode, Result};
5pub use self::request::{Request, RequestBuilder};
6pub use self::response::Response;
7pub(crate) use self::router::Router;
8pub use self::router::{FromParams, IntoResponse, Method};
9
10use std::borrow::Cow;
11use std::fmt::{self, Debug, Display, Formatter};
12
13use lsp_types::NumberOrString;
14use serde::de::{self, Deserializer};
15use serde::ser::Serializer;
16use serde::{Deserialize, Serialize};
17
18mod error;
19mod request;
20mod response;
21mod router;
22
23#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
25#[serde(untagged)]
26#[derive(Default)]
27pub enum Id {
28 Number(i64),
30 String(String),
32 #[default]
38 Null,
39}
40
41impl Display for Id {
42 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
43 match self {
44 Id::Number(id) => Display::fmt(id, f),
45 Id::String(id) => Debug::fmt(id, f),
46 Id::Null => f.write_str("null"),
47 }
48 }
49}
50
51impl From<i64> for Id {
52 fn from(n: i64) -> Self {
53 Id::Number(n)
54 }
55}
56
57impl From<&'_ str> for Id {
58 fn from(s: &'_ str) -> Self {
59 Id::String(s.to_string())
60 }
61}
62
63impl From<String> for Id {
64 fn from(s: String) -> Self {
65 Id::String(s)
66 }
67}
68
69impl From<NumberOrString> for Id {
70 fn from(num_or_str: NumberOrString) -> Self {
71 match num_or_str {
72 NumberOrString::Number(num) => Id::Number(num as i64),
73 NumberOrString::String(s) => Id::String(s),
74 }
75 }
76}
77
78#[derive(Clone, Debug, PartialEq)]
79struct Version;
80
81impl<'de> Deserialize<'de> for Version {
82 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
83 where
84 D: Deserializer<'de>,
85 {
86 #[derive(Deserialize)]
87 struct Inner<'a>(#[serde(borrow)] Cow<'a, str>);
88
89 let Inner(ver) = Inner::deserialize(deserializer)?;
90
91 match ver.as_ref() {
92 "2.0" => Ok(Version),
93 _ => Err(de::Error::custom("expected JSON-RPC version \"2.0\"")),
94 }
95 }
96}
97
98impl Serialize for Version {
99 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
100 where
101 S: Serializer,
102 {
103 serializer.serialize_str("2.0")
104 }
105}
106
107#[derive(Deserialize, Serialize)]
109#[cfg_attr(test, derive(Debug, PartialEq))]
110#[serde(untagged)]
111pub(crate) enum Message {
112 Response(Response),
114 Request(Request),
116}
117
118#[cfg(test)]
119mod tests {
120 use serde_json::json;
121
122 use super::*;
123
124 #[test]
125 fn incoming_from_str_or_value() {
126 let v = json!({"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":0});
127 let from_str: Message = serde_json::from_str(&v.to_string()).unwrap();
128 let from_value: Message = serde_json::from_value(v).unwrap();
129 assert_eq!(from_str, from_value);
130 }
131
132 #[test]
133 fn outgoing_from_str_or_value() {
134 let v = json!({"jsonrpc":"2.0","result":{},"id":1});
135 let from_str: Message = serde_json::from_str(&v.to_string()).unwrap();
136 let from_value: Message = serde_json::from_value(v).unwrap();
137 assert_eq!(from_str, from_value);
138 }
139
140 #[test]
141 fn parses_incoming_message() {
142 let server_request =
143 json!({"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":0});
144 let incoming = serde_json::from_value(server_request).unwrap();
145 assert!(matches!(incoming, Message::Request(_)));
146
147 let server_notif = json!({"jsonrpc":"2.0","method":"initialized","params":{}});
148 let incoming = serde_json::from_value(server_notif).unwrap();
149 assert!(matches!(incoming, Message::Request(_)));
150
151 let client_request = json!({"jsonrpc":"2.0","id":0,"result":[null]});
152 let incoming = serde_json::from_value(client_request).unwrap();
153 assert!(matches!(incoming, Message::Response(_)));
154 }
155
156 #[test]
157 fn parses_outgoing_message() {
158 let client_request = json!({"jsonrpc":"2.0","method":"workspace/configuration","params":{"scopeUri":null,"section":"foo"},"id":0});
159 let outgoing = serde_json::from_value(client_request).unwrap();
160 assert!(matches!(outgoing, Message::Request(_)));
161
162 let client_notif = json!({"jsonrpc":"2.0","method":"window/logMessage","params":{"message":"foo","type":0}});
163 let outgoing = serde_json::from_value(client_notif).unwrap();
164 assert!(matches!(outgoing, Message::Request(_)));
165
166 let server_response = json!({"jsonrpc":"2.0","id":0,"result":[null]});
167 let outgoing = serde_json::from_value(server_response).unwrap();
168 assert!(matches!(outgoing, Message::Response(_)));
169 }
170
171 #[test]
172 fn parses_invalid_server_request() {
173 let unknown_method = json!({"jsonrpc":"2.0","method":"foo"});
174 let incoming = serde_json::from_value(unknown_method).unwrap();
175 assert!(matches!(incoming, Message::Request(_)));
176
177 let unknown_method_with_id = json!({"jsonrpc":"2.0","method":"foo","id":0});
178 let incoming = serde_json::from_value(unknown_method_with_id).unwrap();
179 assert!(matches!(incoming, Message::Request(_)));
180
181 let missing_method = json!({"jsonrpc":"2.0"});
182 let incoming = serde_json::from_value(missing_method).unwrap();
183 assert!(matches!(incoming, Message::Request(_)));
184
185 let missing_method_with_id = json!({"jsonrpc":"2.0","id":0});
186 let incoming = serde_json::from_value(missing_method_with_id).unwrap();
187 assert!(matches!(incoming, Message::Request(_)));
188 }
189
190 #[test]
191 fn accepts_null_request_id() {
192 let request_id: Id = serde_json::from_value(json!(null)).unwrap();
193 assert_eq!(request_id, Id::Null);
194 }
195
196 #[test]
197 fn accepts_negative_integer_request_id() {
198 let request_id: Id = serde_json::from_value(json!(-1)).unwrap();
199 assert_eq!(request_id, Id::Number(-1));
200 }
201}