cuprate_json_rpc/
response.rs

1//! JSON-RPC 2.0 response object.
2
3//---------------------------------------------------------------------------------------------------- Use
4use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
5
6use crate::{error::ErrorObject, id::Id, version::Version};
7
8//---------------------------------------------------------------------------------------------------- Response
9/// [The response object](https://www.jsonrpc.org/specification#response_object).
10///
11/// The generic `T` is the response payload, i.e. it is the
12/// type that holds both the `method` and `params`.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Response<T> {
15    /// JSON-RPC protocol version; always `2.0`.
16    pub jsonrpc: Version,
17
18    /// This field must always be present in serialized JSON.
19    ///
20    /// ### JSON-RPC 2.0 rules
21    /// - The [`Response`]'s ID must be the same as the [`Request`](crate::Request)
22    /// - If the `Request` omitted the `id` field, there should be no `Response`
23    /// - If there was an error in detecting the `Request`'s ID, the `Response` must contain an [`Id::Null`]
24    pub id: Id,
25
26    /// The response payload.
27    ///
28    /// ### JSON-RPC 2.0 rules
29    /// - This must be [`Ok`] upon success
30    /// - This must be [`Err`] upon error
31    /// - This can be any (de)serializable data `T` on success
32    /// - This must be [`ErrorObject`] on errors
33    pub payload: Result<T, ErrorObject>,
34}
35
36impl<T> Response<T> {
37    /// Creates a successful response.
38    ///
39    /// ```rust
40    /// use cuprate_json_rpc::{Id, Response};
41    ///
42    /// let ok = Response::ok(Id::Num(123), "OK");
43    /// let json = serde_json::to_string(&ok).unwrap();
44    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":123,"result":"OK"}"#);
45    /// ```
46    pub const fn ok(id: Id, result: T) -> Self {
47        Self {
48            jsonrpc: Version,
49            id,
50            payload: Ok(result),
51        }
52    }
53
54    /// Creates an error response.
55    ///
56    /// ```rust
57    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
58    ///
59    /// let err = ErrorObject {
60    ///     code: 0.into(),
61    ///     message: "m".into(),
62    ///     data: Some("d".into()),
63    /// };
64    ///
65    /// let ok = Response::<()>::err(Id::Num(123), err);
66    /// let json = serde_json::to_string(&ok).unwrap();
67    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":123,"error":{"code":0,"message":"m","data":"d"}}"#);
68    /// ```
69    pub const fn err(id: Id, error: ErrorObject) -> Self {
70        Self {
71            jsonrpc: Version,
72            id,
73            payload: Err(error),
74        }
75    }
76
77    /// Creates an error response using [`ErrorObject::parse_error`].
78    ///
79    /// ```rust
80    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
81    ///
82    /// let ok = Response::<()>::parse_error(Id::Num(0));
83    /// let json = serde_json::to_string(&ok).unwrap();
84    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":0,"error":{"code":-32700,"message":"Parse error"}}"#);
85    /// ```
86    pub const fn parse_error(id: Id) -> Self {
87        Self {
88            jsonrpc: Version,
89            payload: Err(ErrorObject::parse_error()),
90            id,
91        }
92    }
93
94    /// Creates an error response using [`ErrorObject::invalid_request`].
95    ///
96    /// ```rust
97    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
98    ///
99    /// let ok = Response::<()>::invalid_request(Id::Num(0));
100    /// let json = serde_json::to_string(&ok).unwrap();
101    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":0,"error":{"code":-32600,"message":"Invalid Request"}}"#);
102    /// ```
103    pub const fn invalid_request(id: Id) -> Self {
104        Self {
105            jsonrpc: Version,
106            payload: Err(ErrorObject::invalid_request()),
107            id,
108        }
109    }
110
111    /// Creates an error response using [`ErrorObject::method_not_found`].
112    ///
113    /// ```rust
114    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
115    ///
116    /// let ok = Response::<()>::method_not_found(Id::Num(0));
117    /// let json = serde_json::to_string(&ok).unwrap();
118    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":0,"error":{"code":-32601,"message":"Method not found"}}"#);
119    /// ```
120    pub const fn method_not_found(id: Id) -> Self {
121        Self {
122            jsonrpc: Version,
123            payload: Err(ErrorObject::method_not_found()),
124            id,
125        }
126    }
127
128    /// Creates an error response using [`ErrorObject::invalid_params`].
129    ///
130    /// ```rust
131    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
132    ///
133    /// let ok = Response::<()>::invalid_params(Id::Num(0));
134    /// let json = serde_json::to_string(&ok).unwrap();
135    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":0,"error":{"code":-32602,"message":"Invalid params"}}"#);
136    /// ```
137    pub const fn invalid_params(id: Id) -> Self {
138        Self {
139            jsonrpc: Version,
140            payload: Err(ErrorObject::invalid_params()),
141            id,
142        }
143    }
144
145    /// Creates an error response using [`ErrorObject::internal_error`].
146    ///
147    /// ```rust
148    /// use cuprate_json_rpc::{Id, Response, error::{ErrorObject, ErrorCode}};
149    ///
150    /// let ok = Response::<()>::internal_error(Id::Num(0));
151    /// let json = serde_json::to_string(&ok).unwrap();
152    /// assert_eq!(json, r#"{"jsonrpc":"2.0","id":0,"error":{"code":-32603,"message":"Internal error"}}"#);
153    /// ```
154    pub const fn internal_error(id: Id) -> Self {
155        Self {
156            jsonrpc: Version,
157            payload: Err(ErrorObject::internal_error()),
158            id,
159        }
160    }
161}
162
163//---------------------------------------------------------------------------------------------------- Trait impl
164impl<T> std::fmt::Display for Response<T>
165where
166    T: Serialize,
167{
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        match serde_json::to_string_pretty(self) {
170            Ok(json) => write!(f, "{json}"),
171            Err(_) => Err(std::fmt::Error),
172        }
173    }
174}
175
176//---------------------------------------------------------------------------------------------------- Serde impl
177impl<T> Serialize for Response<T>
178where
179    T: Serialize,
180{
181    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
182    where
183        S: Serializer,
184    {
185        let mut s = serializer.serialize_struct("Response", 3)?;
186
187        s.serialize_field("jsonrpc", &self.jsonrpc)?;
188
189        // This member is required.
190        //
191        // Even if `null`, or the client `Request` didn't include one.
192        s.serialize_field("id", &self.id)?;
193
194        match &self.payload {
195            Ok(r) => s.serialize_field("result", r)?,
196            Err(e) => s.serialize_field("error", e)?,
197        }
198
199        s.end()
200    }
201}
202
203// [`Response`] has a manual deserialization implementation because
204// we need to confirm `result` and `error` don't both exist:
205//
206// > Either the result member or error member MUST be included, but both members MUST NOT be included.
207//
208// <https://www.jsonrpc.org/specification#error_object>
209impl<'de, T> Deserialize<'de> for Response<T>
210where
211    T: Deserialize<'de> + 'de,
212{
213    fn deserialize<D: Deserializer<'de>>(der: D) -> Result<Self, D::Error> {
214        use std::marker::PhantomData;
215
216        use serde::de::{Error, MapAccess, Visitor};
217
218        /// This type represents the key values within [`Response`].
219        enum Key {
220            /// "jsonrpc" field.
221            JsonRpc,
222            /// "result" field.
223            Result,
224            /// "error" field.
225            Error,
226            /// "id" field.
227            Id,
228            /// Any other unknown field (ignored).
229            Unknown,
230        }
231
232        // Deserialization for [`Response`]'s key fields.
233        //
234        // This ignores unknown keys.
235        impl<'de> Deserialize<'de> for Key {
236            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
237            where
238                D: Deserializer<'de>,
239            {
240                /// Serde visitor for [`Response`]'s key fields.
241                struct KeyVisitor;
242
243                impl Visitor<'_> for KeyVisitor {
244                    type Value = Key;
245
246                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
247                        formatter.write_str("`jsonrpc`, `id`, `result`, `error`")
248                    }
249
250                    fn visit_str<E>(self, string: &str) -> Result<Key, E>
251                    where
252                        E: Error,
253                    {
254                        // PERF: this match is in order of how this library serializes fields.
255                        match string {
256                            "jsonrpc" => Ok(Key::JsonRpc),
257                            "id" => Ok(Key::Id),
258                            "result" => Ok(Key::Result),
259                            "error" => Ok(Key::Error),
260                            // Ignore any other keys that appear
261                            // and continue deserialization.
262                            _ => Ok(Key::Unknown),
263                        }
264                    }
265                }
266
267                deserializer.deserialize_identifier(KeyVisitor)
268            }
269        }
270
271        /// Serde visitor for the key-value map of [`Response`].
272        struct MapVisit<T>(PhantomData<T>);
273
274        // Deserialization for [`Response`]'s key and values (the JSON map).
275        impl<'de, T> Visitor<'de> for MapVisit<T>
276        where
277            T: Deserialize<'de> + 'de,
278        {
279            type Value = Response<T>;
280
281            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
282                formatter.write_str("JSON-RPC 2.0 Response")
283            }
284
285            /// This is a loop that goes over every key-value pair
286            /// and fills out the necessary fields.
287            ///
288            /// If both `result/error` appear then this
289            /// deserialization will error, as to
290            /// follow the JSON-RPC 2.0 specification.
291            fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
292                // Initialize values.
293                let mut jsonrpc = None;
294                let mut payload = None;
295                let mut id = None;
296
297                // Loop over map, filling values.
298                while let Some(key) = map.next_key::<Key>()? {
299                    // PERF: this match is in order of how this library serializes fields.
300                    match key {
301                        Key::JsonRpc => jsonrpc = Some(map.next_value::<Version>()?),
302                        Key::Id => id = Some(map.next_value::<Id>()?),
303                        Key::Result => {
304                            if payload.is_none() {
305                                payload = Some(Ok(map.next_value::<T>()?));
306                            } else {
307                                return Err(Error::duplicate_field("result/error"));
308                            }
309                        }
310                        Key::Error => {
311                            if payload.is_none() {
312                                payload = Some(Err(map.next_value::<ErrorObject>()?));
313                            } else {
314                                return Err(Error::duplicate_field("result/error"));
315                            }
316                        }
317                        Key::Unknown => {
318                            map.next_value::<serde::de::IgnoredAny>()?;
319                        }
320                    }
321                }
322
323                // Make sure all our key-value pairs are set and correct.
324                match (jsonrpc, id, payload) {
325                    // Response with a single `result` or `error`.
326                    (Some(jsonrpc), Some(id), Some(payload)) => Ok(Response {
327                        jsonrpc,
328                        id,
329                        payload,
330                    }),
331
332                    // No fields existed.
333                    (None, None, None) => Err(Error::missing_field("jsonrpc + id + result/error")),
334
335                    // Some field was missing.
336                    (None, _, _) => Err(Error::missing_field("jsonrpc")),
337                    (_, None, _) => Err(Error::missing_field("id")),
338                    (_, _, None) => Err(Error::missing_field("result/error")),
339                }
340            }
341        }
342
343        /// All expected fields of the [`Response`] type.
344        const FIELDS: &[&str; 4] = &["jsonrpc", "id", "result", "error"];
345        der.deserialize_struct("Response", FIELDS, MapVisit(PhantomData))
346    }
347}
348
349//---------------------------------------------------------------------------------------------------- TESTS
350#[cfg(test)]
351mod test {
352    use serde_json::json;
353
354    use super::*;
355    use crate::id::Id;
356
357    /// Basic serde test on OK results.
358    #[test]
359    fn serde_result() {
360        let result = String::from("result_ok");
361        let id = Id::Num(123);
362        let req = Response::ok(id.clone(), result.clone());
363
364        let ser: String = serde_json::to_string(&req).unwrap();
365        let de: Response<String> = serde_json::from_str(&ser).unwrap();
366
367        assert_eq!(de.payload.unwrap(), result);
368        assert_eq!(de.id, id);
369    }
370
371    /// Basic serde test on errors.
372    #[test]
373    fn serde_error() {
374        let error = ErrorObject::internal_error();
375        let id = Id::Num(123);
376        let req: Response<String> = Response::err(id.clone(), error.clone());
377
378        let ser: String = serde_json::to_string(&req).unwrap();
379        let de: Response<String> = serde_json::from_str(&ser).unwrap();
380
381        assert_eq!(de.payload.unwrap_err(), error);
382        assert_eq!(de.id, id);
383    }
384
385    /// Test that the `result` and `error` fields are mutually exclusive.
386    #[test]
387    #[should_panic(
388        expected = "called `Result::unwrap()` on an `Err` value: Error(\"duplicate field `result/error`\", line: 0, column: 0)"
389    )]
390    fn result_error_mutually_exclusive() {
391        let e = ErrorObject::internal_error();
392        let j = json!({
393            "jsonrpc": "2.0",
394            "id": 0,
395            "result": "",
396            "error": e
397        });
398        serde_json::from_value::<Response<String>>(j).unwrap();
399    }
400
401    /// Test that the `result` and `error` fields can repeat (and get overwritten).
402    #[test]
403    #[should_panic(
404        expected = "called `Result::unwrap()` on an `Err` value: Error(\"duplicate field `result/error`\", line: 1, column: 45)"
405    )]
406    fn result_repeat() {
407        // `result`
408        let json = r#"{"jsonrpc":"2.0","id":0,"result":"a","result":"b"}"#;
409        serde_json::from_str::<Response<String>>(json).unwrap();
410    }
411
412    /// Test that the `error` field cannot repeat.
413    #[test]
414    #[should_panic(
415        expected = "called `Result::unwrap()` on an `Err` value: Error(\"duplicate field `result/error`\", line: 1, column: 83)"
416    )]
417    fn error_repeat() {
418        let e = ErrorObject::invalid_request();
419        let e = serde_json::to_string(&e).unwrap();
420        let json = format!(r#"{{"jsonrpc":"2.0","id":0,"error":{e},"error":{e}}}"#);
421        serde_json::from_str::<Response<String>>(&json).unwrap();
422    }
423
424    /// Test that the `id` field must exist.
425    #[test]
426    #[should_panic(
427        expected = "called `Result::unwrap()` on an `Err` value: Error(\"missing field `id`\", line: 0, column: 0)"
428    )]
429    fn id_must_exist() {
430        let j = json!({
431            "jsonrpc": "2.0",
432            "result": "",
433        });
434        serde_json::from_value::<Response<String>>(j).unwrap();
435    }
436
437    /// Tests that non-ordered fields still deserialize okay.
438    #[test]
439    fn deserialize_out_of_order_keys() {
440        let e = ErrorObject::internal_error();
441        let j = json!({
442            "error": e,
443            "id": 0,
444            "jsonrpc": "2.0"
445        });
446        let resp = serde_json::from_value::<Response<String>>(j).unwrap();
447        assert_eq!(resp, Response::internal_error(Id::Num(0)));
448
449        let ok = Response::ok(Id::Num(0), "OK".to_string());
450        let j = json!({
451            "result": "OK",
452            "id": 0,
453            "jsonrpc": "2.0"
454        });
455        let resp = serde_json::from_value::<Response<String>>(j).unwrap();
456        assert_eq!(resp, ok);
457    }
458
459    /// Asserts that fields must be `lowercase`.
460    #[test]
461    #[should_panic(
462        expected = "called `Result::unwrap()` on an `Err` value: Error(\"missing field `jsonrpc`\", line: 1, column: 40)"
463    )]
464    fn lowercase() {
465        let mixed_case = r#"{"jSoNRPC":"2.0","id":123,"result":"OK"}"#;
466        serde_json::from_str::<Response<String>>(mixed_case).unwrap();
467    }
468
469    /// Tests that unknown fields are ignored, and deserialize continues.
470    /// Also that unicode and backslashes work.
471    #[test]
472    fn unknown_fields_and_unicode() {
473        let e = ErrorObject::internal_error();
474        let j = json!({
475            "error": e,
476            "\u{00f8}": 123,
477            "id": 0,
478            "unknown_field": 123,
479            "jsonrpc": "2.0",
480            "unknown_field": 123
481        });
482        let resp = serde_json::from_value::<Response<String>>(j).unwrap();
483        assert_eq!(resp, Response::internal_error(Id::Num(0)));
484    }
485}