1use std::fmt;
2
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use serde_json::Value;
5
6use crate::{
7 error::{Error, ErrorCode},
8 id::Id,
9 v2::version::Version,
10};
11
12#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
14#[serde(deny_unknown_fields)]
15pub struct Success<T = Value> {
16 pub jsonrpc: Version,
18 pub result: T,
20 pub id: Id,
24}
25
26impl<T: Serialize> fmt::Display for Success<T> {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 let json = serde_json::to_string(self).expect("`Success` is serializable");
29 write!(f, "{}", json)
30 }
31}
32
33impl<T: Serialize + DeserializeOwned> Success<T> {
34 pub fn new(result: T, id: Id) -> Self {
36 Self {
37 jsonrpc: Version::V2_0,
38 result,
39 id,
40 }
41 }
42}
43
44#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
46#[serde(deny_unknown_fields)]
47pub struct Failure {
48 pub jsonrpc: Version,
50 pub error: Error,
52 pub id: Option<Id>,
59}
60
61impl fmt::Display for Failure {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 let json = serde_json::to_string(self).expect("`Failure` is serializable");
64 write!(f, "{}", json)
65 }
66}
67
68impl Failure {
69 pub fn new(error: Error, id: Option<Id>) -> Self {
71 Self {
72 jsonrpc: Version::V2_0,
73 error,
74 id,
75 }
76 }
77}
78
79#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
81#[serde(deny_unknown_fields)]
82#[serde(untagged)]
83pub enum Output<T = Value> {
84 Success(Success<T>),
86 Failure(Failure),
88}
89
90impl<T: Serialize> fmt::Display for Output<T> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 let json = serde_json::to_string(self).expect("`Output` is serializable");
93 write!(f, "{}", json)
94 }
95}
96
97impl<T: Serialize + DeserializeOwned> Output<T> {
98 pub fn success(result: T, id: Id) -> Self {
100 Self::Success(Success::new(result, id))
101 }
102
103 pub fn failure(error: Error, id: Option<Id>) -> Self {
105 Self::Failure(Failure::new(error, id))
106 }
107
108 pub fn invalid_request(id: Option<Id>) -> Self {
110 Self::Failure(Failure::new(Error::new(ErrorCode::InvalidRequest), id))
111 }
112
113 pub fn version(&self) -> Version {
115 match self {
116 Self::Success(s) => s.jsonrpc,
117 Self::Failure(f) => f.jsonrpc,
118 }
119 }
120
121 pub fn id(&self) -> Option<Id> {
123 match self {
124 Self::Success(s) => Some(s.id.clone()),
125 Self::Failure(f) => f.id.clone(),
126 }
127 }
128}
129
130impl<T: Serialize + DeserializeOwned> From<Output<T>> for Result<T, Error> {
131 fn from(output: Output<T>) -> Result<T, Error> {
134 match output {
135 Output::Success(s) => Ok(s.result),
136 Output::Failure(f) => Err(f.error),
137 }
138 }
139}
140
141#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
143#[serde(deny_unknown_fields)]
144#[serde(untagged)]
145pub enum Response<T = Value> {
146 Single(Output<T>),
148 Batch(Vec<Output<T>>),
150}
151
152impl<T: Serialize> fmt::Display for Response<T> {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 let json = serde_json::to_string(self).expect("`Response` is serializable");
155 write!(f, "{}", json)
156 }
157}
158
159impl<T> From<Success<T>> for Response<T> {
160 fn from(success: Success<T>) -> Self {
161 Response::Single(Output::<T>::Success(success))
162 }
163}
164
165impl<T> From<Failure> for Response<T> {
166 fn from(failure: Failure) -> Self {
167 Response::Single(Output::<T>::Failure(failure))
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 fn success_response_cases() -> Vec<(Success, &'static str)> {
176 vec![(
177 Success {
179 jsonrpc: Version::V2_0,
180 result: Value::Bool(true),
181 id: Id::Num(1),
182 },
183 r#"{"jsonrpc":"2.0","result":true,"id":1}"#,
184 )]
185 }
186
187 fn failure_response_cases() -> Vec<(Failure, &'static str)> {
188 vec![
189 (
190 Failure {
192 jsonrpc: Version::V2_0,
193 error: Error::parse_error(),
194 id: Some(Id::Num(1)),
195 },
196 r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":1}"#,
197 ),
198 (
199 Failure {
201 jsonrpc: Version::V2_0,
202 error: Error::parse_error(),
203 id: None,
204 },
205 r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#,
206 ),
207 ]
208 }
209
210 #[test]
211 fn success_response_serialization() {
212 for (success_response, expect) in success_response_cases() {
213 let ser = serde_json::to_string(&success_response).unwrap();
214 assert_eq!(ser, expect);
215 let de = serde_json::from_str::<Success>(expect).unwrap();
216 assert_eq!(de, success_response);
217 }
218 }
219
220 #[test]
221 fn failure_response_serialization() {
222 for (failure_response, expect) in failure_response_cases() {
223 let ser = serde_json::to_string(&failure_response).unwrap();
224 assert_eq!(ser, expect);
225 let de = serde_json::from_str::<Failure>(expect).unwrap();
226 assert_eq!(de, failure_response);
227 }
228 }
229
230 #[test]
231 fn response_output_serialization() {
232 for (success_response, expect) in success_response_cases() {
233 let response_output = Output::Success(success_response);
234 assert_eq!(serde_json::to_string(&response_output).unwrap(), expect);
235 assert_eq!(serde_json::from_str::<Output>(expect).unwrap(), response_output);
236 }
237
238 for (failure_response, expect) in failure_response_cases() {
239 let response_output = Output::Failure(failure_response);
240 assert_eq!(serde_json::to_string(&response_output).unwrap(), expect);
241 assert_eq!(serde_json::from_str::<Output>(expect).unwrap(), response_output);
242 }
243 }
244
245 #[test]
246 fn response_serialization() {
247 for (success_resp, expect) in success_response_cases() {
248 let success_response = Response::Single(Output::Success(success_resp.clone()));
249 assert_eq!(serde_json::to_string(&success_response).unwrap(), expect);
250 assert_eq!(serde_json::from_str::<Response>(expect).unwrap(), success_response);
251 }
252
253 for (failure_resp, expect) in failure_response_cases() {
254 let failure_response = Response::Single(Output::Failure(failure_resp.clone()));
255 assert_eq!(serde_json::to_string(&failure_response).unwrap(), expect);
256 assert_eq!(serde_json::from_str::<Response>(expect).unwrap(), failure_response);
257 }
258
259 for ((success_resp, success_expect), (failure_resp, failure_expect)) in
260 success_response_cases().into_iter().zip(failure_response_cases())
261 {
262 let batch_response = Response::Batch(vec![Output::Success(success_resp), Output::Failure(failure_resp)]);
263 let batch_expect = format!("[{},{}]", success_expect, failure_expect);
264 assert_eq!(serde_json::to_string(&batch_response).unwrap(), batch_expect);
265 assert_eq!(serde_json::from_str::<Response>(&batch_expect).unwrap(), batch_response);
266 }
267 }
268
269 #[test]
270 fn invalid_response() {
271 let cases = vec![
272 r#"{"jsonrpc":"2.0","result":true,"id":1,"unknown":[]}"#,
274 r#"{"jsonrpc":"2.0","error":{"code": -32700,"message": "Parse error"},"id":1,"unknown":[]}"#,
275 r#"{"jsonrpc":"2.0","result":true,"error":{"code": -32700,"message": "Parse error"},"id":1}"#,
276 r#"{"jsonrpc":"2.0","id":1}"#,
277 r#"{"jsonrpc":"2.0","unknown":[]}"#,
278 ];
279
280 for case in cases {
281 let response = serde_json::from_str::<Response>(case);
282 assert!(response.is_err());
283 }
284 }
285
286 #[test]
287 fn valid_response() {
288 let cases = vec![
289 r#"{"jsonrpc":"2.0","result":true,"id":1}"#,
291 r#"{"jsonrpc":"2.0","error":{"code": -32700,"message": "Parse error"},"id":1}"#,
292 r#"{"jsonrpc":"2.0","error":{"code": -32700,"message": "Parse error"},"id":null}"#,
293 ];
294
295 for case in cases {
296 let response = serde_json::from_str::<Response>(case);
297 assert!(response.is_ok());
298 }
299 }
300}