1pub mod error;
2
3use base64::Engine as _;
4use serde::de::DeserializeOwned;
5use serde::{Deserialize, Serialize};
6use std::str::FromStr;
7
8pub use crate::json_rpc::error::{DefaultError, ErrorData};
9use crate::lsps0::parameter_validation;
10pub use crate::no_params::NoParams;
11
12#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
13#[serde(untagged)]
14pub enum JsonRpcId {
15 String(String),
16 Number(i64),
17 None,
18}
19
20impl PartialEq<serde_json::Value> for JsonRpcId {
21 fn eq(&self, value: &serde_json::Value) -> bool {
22 match self {
23 Self::String(s) => value == s,
24 Self::Number(n) => value == n,
25 Self::None => value == &serde_json::Value::Null,
26 }
27 }
28}
29
30impl PartialEq<&str> for JsonRpcId {
31 fn eq(&self, value: &&str) -> bool {
32 match self {
33 Self::String(s) => s == value,
34 Self::Number(_) => false,
35 Self::None => false,
36 }
37 }
38}
39
40impl From<&str> for JsonRpcId {
41 fn from(value: &str) -> Self {
42 Self::String(value.to_string())
43 }
44}
45
46impl FromStr for JsonRpcId {
47 type Err = anyhow::Error;
48
49 fn from_str(value: &str) -> Result<Self, Self::Err> {
50 Ok(Self::String(value.to_string()))
51 }
52}
53
54pub fn generate_random_rpc_id() -> JsonRpcId {
59 let seed: [u8; 10] = rand::random();
61 let str_id = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(seed);
62 JsonRpcId::String(str_id)
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
70pub struct JsonRpcMethod<'a, I, O, E> {
71 pub method: &'a str,
72 #[serde(skip_serializing)]
73 request: std::marker::PhantomData<I>,
74 #[serde(skip_serializing)]
75 return_type: std::marker::PhantomData<O>,
76 #[serde(skip_serializing)]
77 error_type: std::marker::PhantomData<E>,
78}
79
80impl<'a, I, O, E> JsonRpcMethod<'a, I, O, E> {
81 pub const fn new(method: &'a str) -> Self {
82 Self {
83 method,
84 request: std::marker::PhantomData,
85 return_type: std::marker::PhantomData,
86 error_type: std::marker::PhantomData,
87 }
88 }
89
90 pub const fn name(&self) -> &'a str {
91 self.method
92 }
93
94 pub fn create_request(&self, params: I, json_rpc_id: JsonRpcId) -> JsonRpcRequest<I> {
96 JsonRpcRequest::<I> {
97 jsonrpc: String::from("2.0"),
98 id: json_rpc_id,
99 method: self.method.into(),
100 params,
101 }
102 }
103
104 pub fn create_ok_response(
105 &self,
106 request: JsonRpcRequest<I>,
107 result: O,
108 ) -> JsonRpcResponse<O, E> {
109 JsonRpcResponse::Ok(JsonRpcResponseSuccess {
110 jsonrpc: String::from("2.0"),
111 id: request.id.clone(),
112 result,
113 })
114 }
115
116 pub fn into_typed_request(
117 &self,
118 request: JsonRpcRequest<serde_json::Value>,
119 ) -> Result<JsonRpcRequest<I>, ErrorData>
120 where
121 I: DeserializeOwned + parameter_validation::ExpectedFields,
122 {
123 let params = request.params;
124 let params: I = parameter_validation::from_value(params)?;
125
126 let request = JsonRpcRequest::<I> {
127 id: request.id,
128 jsonrpc: request.jsonrpc,
129 method: request.method,
130 params: params,
131 };
132
133 Ok(request)
134 }
135}
136
137impl<O, E> JsonRpcMethod<'_, NoParams, O, E> {
138 pub fn create_request_no_params(&self, json_rpc_id: JsonRpcId) -> JsonRpcRequest<NoParams> {
139 self.create_request(NoParams, json_rpc_id)
140 }
141}
142
143impl<'a, I, O, E> std::convert::From<&'a JsonRpcMethod<'a, I, O, E>> for String {
144 fn from(value: &JsonRpcMethod<I, O, E>) -> Self {
145 value.method.into()
146 }
147}
148
149impl<'de, I, O, E> JsonRpcMethod<'de, I, O, E>
150where
151 O: Deserialize<'de>,
152 E: Deserialize<'de>,
153{
154 pub fn parse_json_response_str(
155 &self,
156 json_str: &'de str,
157 ) -> Result<JsonRpcResponse<O, E>, serde_json::Error> {
158 serde_json::from_str(json_str)
159 }
160}
161
162impl<I, O, E> JsonRpcMethod<'_, I, O, E>
163where
164 O: DeserializeOwned,
165 E: DeserializeOwned,
166{
167 pub fn parse_json_response_value(
168 &self,
169 json_value: serde_json::Value,
170 ) -> Result<JsonRpcResponse<O, E>, serde_json::Error> {
171 serde_json::from_value(json_value)
172 }
173}
174
175#[derive(Serialize, Deserialize, Debug, Clone)]
176pub struct JsonRpcRequest<I> {
177 pub jsonrpc: String,
178 pub id: JsonRpcId,
179 pub method: String,
180 pub params: I,
181}
182
183impl<I> JsonRpcRequest<I> {
184 pub fn new<O, E>(method: JsonRpcMethod<I, O, E>, params: I) -> Self {
185 Self {
186 jsonrpc: String::from("2.0"),
187 id: generate_random_rpc_id(),
188 method: method.method.into(),
189 params,
190 }
191 }
192}
193
194impl JsonRpcRequest<serde_json::Value> {
195 pub fn deserialize<I>(self) -> Result<JsonRpcRequest<I>, serde_json::Error>
196 where
197 I: DeserializeOwned,
198 {
199 let request = JsonRpcRequest {
200 jsonrpc: self.jsonrpc,
201 id: self.id,
202 method: self.method,
203 params: serde_json::from_value(self.params)?,
204 };
205 Ok(request)
206 }
207}
208
209impl JsonRpcRequest<NoParams> {
210 pub fn new_no_params<O, E>(method: JsonRpcMethod<NoParams, O, E>) -> Self {
211 Self {
212 jsonrpc: String::from("2.0"),
213 id: generate_random_rpc_id(),
214 method: method.method.into(),
215 params: NoParams,
216 }
217 }
218}
219
220#[derive(Debug, Serialize, Deserialize)]
221pub struct JsonRpcResponseSuccess<O> {
222 pub id: JsonRpcId,
223 pub result: O,
224 pub jsonrpc: String,
225}
226
227#[derive(Debug, Serialize, Deserialize)]
228pub struct JsonRpcResponseFailure<E> {
229 pub id: JsonRpcId,
230 pub error: ErrorData<E>,
231 pub jsonrpc: String,
232}
233
234#[derive(Debug, Serialize, Deserialize)]
235#[serde(untagged)]
236pub enum JsonRpcResponse<O, E> {
237 Error(JsonRpcResponseFailure<E>),
238 Ok(JsonRpcResponseSuccess<O>),
239}
240
241impl<E, O> JsonRpcResponse<E, O> {
242 pub fn jsonrpc(&self) -> &str {
243 match self {
244 JsonRpcResponse::Ok(j) => &j.jsonrpc,
245 JsonRpcResponse::Error(j) => &j.jsonrpc,
246 }
247 }
248
249 pub fn id(&self) -> &JsonRpcId {
250 match self {
251 JsonRpcResponse::Ok(j) => &j.id,
252 JsonRpcResponse::Error(j) => &j.id,
253 }
254 }
255}
256
257impl<O, E> JsonRpcResponse<O, E> {
258 pub fn success(id: JsonRpcId, output: O) -> Self {
259 let success = JsonRpcResponseSuccess {
260 id,
261 result: output,
262 jsonrpc: String::from("2.0"),
263 };
264
265 JsonRpcResponse::Ok(success)
266 }
267
268 pub fn error(id: JsonRpcId, error: ErrorData<E>) -> Self {
269 let error = JsonRpcResponseFailure {
270 id,
271 error,
272 jsonrpc: String::from("2.0"),
273 };
274
275 JsonRpcResponse::Error(error)
276 }
277}
278
279#[cfg(test)]
280mod test {
281
282 use super::*;
283
284 #[test]
285 fn serialize_json_rpc_request() {
286 let rpc_request = JsonRpcRequest {
287 id: "abcefg".into(),
288 jsonrpc: "2.0".into(),
289 params: NoParams,
290 method: "test.method".into(),
291 };
292
293 let json_str = serde_json::to_string(&rpc_request).unwrap();
294
295 let value: serde_json::Value = serde_json::from_str(&json_str).unwrap();
296 assert_eq!(value.get("jsonrpc").unwrap(), "2.0");
297 assert_eq!(&rpc_request.id, value.get("id").unwrap());
298 assert_eq!(value.get("method").unwrap(), "test.method");
299 assert!(value.get("params").unwrap().as_object().unwrap().is_empty())
300 }
301
302 #[test]
303 fn serialize_json_rpc_response_success() {
304 let rpc_response_ok: JsonRpcResponseSuccess<String> = JsonRpcResponseSuccess {
305 id: JsonRpcId::String("abc".to_string()),
306 result: String::from("result_data"),
307 jsonrpc: String::from("2.0"),
308 };
309
310 let rpc_response: JsonRpcResponse<String, ()> = JsonRpcResponse::Ok(rpc_response_ok);
311
312 let json_str: String = serde_json::to_string(&rpc_response).unwrap();
313
314 let value: serde_json::Value = serde_json::from_str(&json_str).unwrap();
315 assert_eq!(value.get("jsonrpc").unwrap(), "2.0");
316 assert_eq!(value.get("id").unwrap(), "abc");
317 assert_eq!(value.get("result").unwrap(), "result_data")
318 }
319
320 #[test]
321 fn serialize_json_rpc_response_error() {
322 let rpc_response: JsonRpcResponse<String, ()> =
323 JsonRpcResponse::Error(JsonRpcResponseFailure {
324 jsonrpc: String::from("2.0"),
325 id: JsonRpcId::String("abc".to_string()),
326 error: ErrorData {
327 code: -32700,
328 message: String::from("Failed to parse data"),
329 data: None,
330 },
331 });
332
333 let json_str: String = serde_json::to_string(&rpc_response).unwrap();
334
335 let value: serde_json::Value = serde_json::from_str(&json_str).unwrap();
336 assert_eq!(value.get("jsonrpc").unwrap(), "2.0");
337 assert_eq!(value.get("id").unwrap(), "abc");
338 assert_eq!(value.get("error").unwrap().get("code").unwrap(), -32700);
339 assert_eq!(
340 value.get("error").unwrap().get("message").unwrap(),
341 "Failed to parse data"
342 );
343 }
344
345 #[test]
346 fn create_rpc_request_from_call() {
347 let rpc_method = JsonRpcMethod::<NoParams, (), DefaultError>::new("test.method");
348 let json_rpc_id = generate_random_rpc_id();
349 let rpc_request = rpc_method.create_request_no_params(json_rpc_id);
350
351 assert_eq!(rpc_request.method, "test.method");
352 assert_eq!(rpc_request.jsonrpc, "2.0");
353 assert_eq!(rpc_request.params, NoParams);
354 }
355
356 #[test]
357 fn parse_rpc_response_success_from_call() {
358 let rpc_method = JsonRpcMethod::<NoParams, String, DefaultError>::new("test.return_string");
359
360 let json_value = serde_json::json!({
361 "jsonrpc" : "2.0",
362 "result" : "result_data",
363 "id" : "request_id"
364 });
365
366 let json_str = serde_json::to_string(&json_value).unwrap();
367
368 let result = rpc_method.parse_json_response_str(&json_str).unwrap();
369
370 match result {
371 JsonRpcResponse::Error(_) => panic!("Deserialized a good response but got panic"),
372 JsonRpcResponse::Ok(ok) => {
373 assert_eq!(ok.jsonrpc, "2.0");
374 assert_eq!(ok.id, "request_id");
375 assert_eq!(ok.result, "result_data")
376 }
377 }
378 }
379
380 #[test]
381 fn parse_rpc_response_failure_from_call() {
382 let rpc_method = JsonRpcMethod::<NoParams, String, DefaultError>::new("test.return_string");
383
384 let json_value = serde_json::json!({
385 "jsonrpc" : "2.0",
386 "error" : { "code" : -32700, "message" : "Failed to parse response"},
387 "id" : "request_id"
388 });
389
390 let json_str = serde_json::to_string(&json_value).unwrap();
391
392 let result = rpc_method.parse_json_response_str(&json_str).unwrap();
393
394 match result {
395 JsonRpcResponse::Error(err) => {
396 assert_eq!(err.jsonrpc, "2.0");
397
398 assert_eq!(err.error.code, -32700);
399
400 assert_eq!(err.error.message, "Failed to parse response");
401 assert_eq!(err.id, JsonRpcId::String("request_id".to_string()));
402 }
403 JsonRpcResponse::Ok(_ok) => {
404 panic!("Failure deserialized as Ok")
405 }
406 }
407 }
408
409 #[test]
410 fn serialize_json_rpc_id() {
411 let id_str = JsonRpcId::String("id_string".to_string());
412 let id_i64 = JsonRpcId::Number(-12);
413 let id_null = JsonRpcId::None;
414
415 assert_eq!(serde_json::json!(id_str), serde_json::json!("id_string"));
416
417 assert_eq!(serde_json::json!(id_i64), serde_json::json!(-12));
418
419 assert_eq!(serde_json::json!(id_null), serde_json::json!(null))
420 }
421
422 #[test]
423 fn deserialize_default_error() {
424 let data = serde_json::json!({
425 "jsonrpc" : "2.0",
426 "id" : "abcdef",
427 "error" : {
428 "code" : 10,
429 "message" : "Something happened",
430 "data" : { "object" : "I am an unrecegonized object and should be either ignored or parsed" }
431 }
432 });
433
434 let _: JsonRpcResponseFailure<DefaultError> = serde_json::from_value(data).unwrap();
435 }
436}