1use super::{helpers, Error};
2use alloc::string::{String, ToString};
3use core::{fmt, str::FromStr};
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7#[derive(Serialize, Deserialize, Debug, Clone)]
9pub struct Response {
10 pub jsonrpc: String,
12
13 #[serde(skip_serializing_if = "Option::is_none")]
15 pub result: Option<Value>,
16
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub error: Option<Error>,
20
21 pub id: Value,
23}
24
25impl Response {
26 pub fn ok<I, V>(id: I, value: V) -> Self
28 where
29 I: Into<Value>,
30 V: Into<Value>,
31 {
32 Self {
33 jsonrpc: "2.0".to_string(),
34 result: Some(value.into()),
35 error: None,
36 id: id.into(),
37 }
38 }
39
40 pub fn err<I, E>(id: I, err: E) -> Self
42 where
43 I: Into<Value>,
44 E: Into<Error>,
45 {
46 Self {
47 jsonrpc: "2.0".to_string(),
48 result: None,
49 error: Some(err.into()),
50 id: id.into(),
51 }
52 }
53
54 pub fn parse(s: &str) -> Result<(Self, &str), Error> {
56 let (message, remainder) = helpers::get_content_length(s)?;
57 let response = Response::parse_json(message)?;
58 Ok((response, remainder))
59 }
60
61 pub fn parse_json(json: &str) -> Result<Self, Error> {
63 serde_json::from_str(json).map_err(|e| Error {
64 code: Error::INVALID_REQUEST,
65 message: e.to_string(),
66 data: Some(Value::String(json.to_string())),
67 })
68 }
69}
70
71impl<T, E> From<Response> for Result<T, E>
72where
73 T: From<Value>,
74 E: From<Error>,
75{
76 fn from(value: Response) -> Self {
77 match (value.result, value.error) {
78 (Some(result), _) => Ok(result.into()),
79 (_, Some(err)) => Err(err.into()),
80 (_, _) => Err(Error {
81 code: Error::INVALID_REQUEST,
82 message: "the provided respose header is invalid".to_string(),
83 data: None,
84 }
85 .into()),
86 }
87 }
88}
89
90impl fmt::Display for Response {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 serde_json::to_string(&self)
93 .map_err(|_| fmt::Error)
94 .and_then(|m| write!(f, "Content-Length: {}\r\n\r\n{}", m.len(), m))
95 }
96}
97
98impl FromStr for Response {
99 type Err = Error;
100
101 fn from_str(s: &str) -> Result<Self, Self::Err> {
102 Self::parse(s).map(|(json, _)| json)
103 }
104}
105
106#[cfg(feature = "std")]
107mod io {
108 use super::*;
109 use std::io::prelude::*;
110
111 impl Response {
112 pub fn try_from_reader<R>(reader: R) -> Result<(usize, Self), Error>
116 where
117 R: Read,
118 {
119 let (n, contents) = helpers::get_content_from_reader(reader)?;
120 let response = Response::parse_json(&contents)?;
121 Ok((n, response))
122 }
123
124 pub fn try_to_writer<W>(&self, mut writer: W) -> Result<usize, Error>
126 where
127 W: Write,
128 {
129 writer
130 .write(self.to_string().as_bytes())
131 .map_err(|e| Error {
132 code: Error::PARSE_ERROR,
133 message: e.to_string(),
134 data: serde_json::to_value(&self).ok(),
135 })
136 }
137 }
138}