1use std::{borrow::Cow as StdCow, fmt, marker::PhantomData};
30
31use crate::{
32 error::ErrorCode,
33 params::{Id, SubscriptionId, TwoPointZero},
34 request::Notification,
35 ErrorObject, ErrorObjectOwned,
36};
37use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
38
39pub struct Response<'a, T: Clone> {
41 pub jsonrpc: Option<TwoPointZero>,
43 pub payload: ResponsePayload<'a, T>,
45 pub id: Id<'a>,
47}
48
49impl<'a, T: Clone> Response<'a, T> {
50 pub fn new(payload: ResponsePayload<'a, T>, id: Id<'a>) -> Response<'a, T> {
52 Response { jsonrpc: Some(TwoPointZero), payload, id }
53 }
54
55 pub fn into_owned(self) -> Response<'static, T> {
57 Response {
58 jsonrpc: self.jsonrpc,
59 payload: self.payload.into_owned(),
60 id: self.id.into_owned(),
61 }
62 }
63}
64
65impl<T> fmt::Display for Response<'_, T>
66where
67 T: Serialize + Clone,
68{
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.write_str(&serde_json::to_string(&self).expect("valid JSON; qed"))
71 }
72}
73
74impl<T> fmt::Debug for Response<'_, T>
75where
76 T: Serialize + Clone,
77{
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str(&serde_json::to_string(&self).expect("valid JSON; qed"))
80 }
81}
82
83#[derive(Debug)]
86pub struct Success<'a, T> {
87 pub jsonrpc: Option<TwoPointZero>,
89 pub result: T,
91 pub id: Id<'a>,
93}
94
95impl<'a, T: Clone> TryFrom<Response<'a, T>> for Success<'a, T> {
96 type Error = ErrorObjectOwned;
97
98 fn try_from(rp: Response<'a, T>) -> Result<Self, Self::Error> {
99 match rp.payload {
100 ResponsePayload::Error(e) => Err(e.into_owned()),
101 ResponsePayload::Success(r) => {
102 Ok(Success { jsonrpc: rp.jsonrpc, result: r.into_owned(), id: rp.id })
103 }
104 }
105 }
106}
107
108#[derive(Serialize, Deserialize, Debug)]
110pub struct SubscriptionPayload<'a, T> {
111 #[serde(borrow)]
113 pub subscription: SubscriptionId<'a>,
114 pub result: T,
116}
117
118pub type SubscriptionResponse<'a, T> = Notification<'a, SubscriptionPayload<'a, T>>;
121pub type SubscriptionError<'a, T> = Notification<'a, SubscriptionPayloadError<'a, T>>;
124
125#[derive(Serialize, Deserialize, Debug)]
127pub struct SubscriptionPayloadError<'a, T> {
128 #[serde(borrow)]
130 pub subscription: SubscriptionId<'a>,
131 pub error: T,
133}
134
135#[derive(Debug, Clone, PartialEq)]
144pub enum ResponsePayload<'a, T>
145where
146 T: Clone,
147{
148 Success(StdCow<'a, T>),
150 Error(ErrorObject<'a>),
152}
153
154impl<'a, T: Clone> ResponsePayload<'a, T> {
155 pub fn success(t: T) -> Self {
157 Self::Success(StdCow::Owned(t))
158 }
159
160 pub fn success_borrowed(t: &'a T) -> Self {
162 Self::Success(StdCow::Borrowed(t))
163 }
164
165 pub fn into_owned(self) -> ResponsePayload<'static, T> {
167 match self {
168 Self::Error(e) => ResponsePayload::Error(e.into_owned()),
169 Self::Success(r) => ResponsePayload::Success(StdCow::Owned(r.into_owned())),
170 }
171 }
172
173 pub fn error(e: impl Into<ErrorObjectOwned>) -> Self {
175 Self::Error(e.into())
176 }
177
178 pub fn error_borrowed(e: impl Into<ErrorObject<'a>>) -> Self {
180 Self::Error(e.into())
181 }
182}
183
184impl<'a, T: Clone> From<ErrorCode> for ResponsePayload<'a, T> {
185 fn from(code: ErrorCode) -> ResponsePayload<'a, T> {
186 Self::Error(code.into())
187 }
188}
189
190impl<'de, T> Deserialize<'de> for Response<'de, T>
191where
192 T: Deserialize<'de> + Clone,
193{
194 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
195 where
196 D: Deserializer<'de>,
197 T: Deserialize<'de> + Clone,
198 {
199 #[derive(Debug)]
200 enum Field {
201 Jsonrpc,
202 Result,
203 Error,
204 Id,
205 Ignore,
206 }
207
208 impl<'de> Deserialize<'de> for Field {
209 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
210 where
211 D: Deserializer<'de>,
212 {
213 struct FieldVisitor;
214
215 impl serde::de::Visitor<'_> for FieldVisitor {
216 type Value = Field;
217
218 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
219 formatter.write_str("`jsonrpc`, `result`, `error` and `id`")
220 }
221
222 fn visit_str<E>(self, value: &str) -> Result<Field, E>
223 where
224 E: serde::de::Error,
225 {
226 match value {
227 "jsonrpc" => Ok(Field::Jsonrpc),
228 "result" => Ok(Field::Result),
229 "error" => Ok(Field::Error),
230 "id" => Ok(Field::Id),
231 _ => Ok(Field::Ignore),
232 }
233 }
234 }
235 deserializer.deserialize_identifier(FieldVisitor)
236 }
237 }
238
239 struct Visitor<T>(PhantomData<T>);
240
241 impl<T> Visitor<T> {
242 fn new() -> Visitor<T> {
243 Visitor(PhantomData)
244 }
245 }
246
247 impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
248 where
249 T: Deserialize<'de> + Clone + 'de,
250 {
251 type Value = Response<'de, T>;
252
253 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
254 formatter.write_str("struct Response")
255 }
256
257 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
258 where
259 V: serde::de::MapAccess<'de>,
260 {
261 let mut jsonrpc = None;
262 let mut result = None;
263 let mut error = None;
264 let mut id = None;
265 while let Some(key) = map.next_key()? {
266 match key {
267 Field::Result => {
268 if result.is_some() {
269 return Err(serde::de::Error::duplicate_field("result"));
270 }
271 result = Some(map.next_value()?);
272 }
273 Field::Error => {
274 if error.is_some() {
275 return Err(serde::de::Error::duplicate_field("error"));
276 }
277 error = Some(map.next_value()?);
278 }
279 Field::Id => {
280 if id.is_some() {
281 return Err(serde::de::Error::duplicate_field("id"));
282 }
283 id = Some(map.next_value()?);
284 }
285 Field::Jsonrpc => {
286 if jsonrpc.is_some() {
287 return Err(serde::de::Error::duplicate_field("jsonrpc"));
288 }
289 jsonrpc = Some(map.next_value()?);
290 }
291 Field::Ignore => {
292 let _ = map.next_value::<serde::de::IgnoredAny>()?;
293 }
294 }
295 }
296
297 let id = id.ok_or_else(|| serde::de::Error::missing_field("id"))?;
298
299 let response = match (jsonrpc, result, error) {
300 (_, Some(_), Some(_)) => {
301 return Err(serde::de::Error::duplicate_field(
302 "result and error are mutually exclusive",
303 ));
304 }
305 (Some(jsonrpc), Some(result), None) => {
306 Response { jsonrpc, payload: ResponsePayload::Success(result), id }
307 }
308 (Some(jsonrpc), None, Some(err)) => {
309 Response { jsonrpc, payload: ResponsePayload::Error(err), id }
310 }
311 (None, Some(result), _) => {
312 Response { jsonrpc: None, payload: ResponsePayload::Success(result), id }
313 }
314 (None, _, Some(err)) => {
315 Response { jsonrpc: None, payload: ResponsePayload::Error(err), id }
316 }
317 (_, None, None) => return Err(serde::de::Error::missing_field("result/error")),
318 };
319
320 Ok(response)
321 }
322 }
323
324 const FIELDS: &[&str] = &["jsonrpc", "result", "error", "id"];
325 deserializer.deserialize_struct("Response", FIELDS, Visitor::new())
326 }
327}
328
329impl<T> Serialize for Response<'_, T>
330where
331 T: Serialize + Clone,
332{
333 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
334 where
335 S: Serializer,
336 {
337 let mut s = serializer.serialize_struct("Response", 3)?;
338
339 if let Some(field) = &self.jsonrpc {
340 s.serialize_field("jsonrpc", field)?;
341 }
342
343 s.serialize_field("id", &self.id)?;
344
345 match &self.payload {
346 ResponsePayload::Error(err) => s.serialize_field("error", err)?,
347 ResponsePayload::Success(r) => s.serialize_field("result", r)?,
348 };
349
350 s.end()
351 }
352}
353
354#[cfg(test)]
355mod tests {
356
357 use super::{Id, Response, TwoPointZero};
358 use crate::{response::ResponsePayload, ErrorObjectOwned};
359
360 #[test]
361 fn serialize_call_ok_response() {
362 let ser = serde_json::to_string(&Response {
363 jsonrpc: Some(TwoPointZero),
364 payload: ResponsePayload::success("ok"),
365 id: Id::Number(1),
366 })
367 .unwrap();
368 let exp = r#"{"jsonrpc":"2.0","id":1,"result":"ok"}"#;
369 assert_eq!(ser, exp);
370 }
371
372 #[test]
373 fn serialize_call_err_response() {
374 let ser = serde_json::to_string(&Response {
375 jsonrpc: Some(TwoPointZero),
376 payload: ResponsePayload::<()>::error(ErrorObjectOwned::owned(1, "lo", None::<()>)),
377 id: Id::Number(1),
378 })
379 .unwrap();
380 let exp = r#"{"jsonrpc":"2.0","id":1,"error":{"code":1,"message":"lo"}}"#;
381 assert_eq!(ser, exp);
382 }
383
384 #[test]
385 fn serialize_call_response_missing_version_field() {
386 let ser = serde_json::to_string(&Response {
387 jsonrpc: None,
388 payload: ResponsePayload::success("ok"),
389 id: Id::Number(1),
390 })
391 .unwrap();
392 let exp = r#"{"id":1,"result":"ok"}"#;
393 assert_eq!(ser, exp);
394 }
395
396 #[test]
397 fn deserialize_success_call() {
398 let exp = Response {
399 jsonrpc: Some(TwoPointZero),
400 payload: ResponsePayload::success(99_u64),
401 id: Id::Number(11),
402 };
403 let dsr: Response<u64> =
404 serde_json::from_str(r#"{"jsonrpc":"2.0", "result":99, "id":11}"#).unwrap();
405 assert_eq!(dsr.jsonrpc, exp.jsonrpc);
406 assert_eq!(dsr.payload, exp.payload);
407 assert_eq!(dsr.id, exp.id);
408 }
409
410 #[test]
411 fn deserialize_err_call() {
412 let exp = Response {
413 jsonrpc: Some(TwoPointZero),
414 payload: ResponsePayload::error(ErrorObjectOwned::owned(1, "lo", None::<()>)),
415 id: Id::Number(11),
416 };
417 let dsr: Response<()> =
418 serde_json::from_str(r#"{"jsonrpc":"2.0","error":{"code":1,"message":"lo"},"id":11}"#)
419 .unwrap();
420 assert_eq!(dsr.jsonrpc, exp.jsonrpc);
421 assert_eq!(dsr.payload, exp.payload);
422 assert_eq!(dsr.id, exp.id);
423 }
424
425 #[test]
426 fn deserialize_call_missing_version_field() {
427 let exp = Response {
428 jsonrpc: None,
429 payload: ResponsePayload::success(99_u64),
430 id: Id::Number(11),
431 };
432 let dsr: Response<u64> =
433 serde_json::from_str(r#"{"jsonrpc":null, "result":99, "id":11}"#).unwrap();
434 assert_eq!(dsr.jsonrpc, exp.jsonrpc);
435 assert_eq!(dsr.payload, exp.payload);
436 assert_eq!(dsr.id, exp.id);
437 }
438
439 #[test]
440 fn deserialize_with_unknown_field() {
441 let exp = Response {
442 jsonrpc: None,
443 payload: ResponsePayload::success(99_u64),
444 id: Id::Number(11),
445 };
446 let dsr: Response<u64> =
447 serde_json::from_str(r#"{"jsonrpc":null, "result":99, "id":11, "unknown":11}"#)
448 .unwrap();
449 assert_eq!(dsr.jsonrpc, exp.jsonrpc);
450 assert_eq!(dsr.payload, exp.payload);
451 assert_eq!(dsr.id, exp.id);
452 }
453}