jsonrpc_parse/
response.rs

1use bytes::{BufMut, Bytes};
2use serde_derive::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::parse::generate_response_headers;
6use crate::parse::split_bytes;
7use crate::types::Params;
8
9#[derive(Default, Debug, Clone, Serialize, Deserialize)]
10pub struct Response {
11    jsonrpc: String,
12    method: String,
13    id: String,
14    result: Params,
15}
16
17impl Response {
18    pub fn new(method: String, id: String, result: Params) -> Self {
19        let jsonrpc = "2.0".into();
20
21        Response {
22            jsonrpc,
23            method,
24            id,
25            result,
26        }
27    }
28
29    pub fn parse(bytes: Bytes) -> Result<Self, Error> {
30        split_bytes(bytes).and_then(|value| Response::parse_from_json(value))
31    }
32
33    pub fn parse_from_json_bytes(bytes: Bytes) -> Result<Self, Error> {
34        serde_json::from_slice(&bytes[..])
35            .or(Err(Error::ParseError(None)))
36            .and_then(|value| Response::parse_from_json(value))
37    }
38
39    pub fn parse_from_json(value: Value) -> Result<Self, Error> {
40        let id = if let Some(id) = value.get("id") {
41            id.as_str().unwrap().into()
42        } else {
43            " ".into()
44        };
45
46        if value.get("method").is_none() {
47            return Err(Error::MethodNotFound("".into(), id));
48        }
49        let method = value.get("method").unwrap().as_str().unwrap().into();
50
51        if value.get("result").is_some() {
52            let jsonrpc = "2.0".into();
53            let result = value.get("result").unwrap().clone();
54
55            return Ok(Response {
56                jsonrpc,
57                method,
58                id,
59                result,
60            });
61        }
62
63        if value.get("error").is_some() {
64            let code = value
65                .get("error")
66                .unwrap()
67                .get("code")
68                .map_or(-32600, |v| v.as_i64().map_or(-32600, |v| v));
69
70            let message = value
71                .get("error")
72                .unwrap()
73                .get("message")
74                .map_or("Invalid Request", |v| {
75                    v.as_str().map_or("Invalid Request", |v| v)
76                })
77                .into();
78            return Err(Error::ErrorResponse(method, id, code, message));
79        }
80
81        return Err(Error::InvalidResponse(method, id));
82    }
83
84    pub fn deparse(&self) -> Bytes {
85        let body = serde_json::to_string(&self).unwrap();
86
87        let body_bytes = body.as_bytes();
88
89        let mut headers = generate_response_headers(body_bytes.len());
90        headers.put(body_bytes);
91        headers.freeze()
92    }
93
94    pub fn result(&self) -> &Params {
95        &self.result
96    }
97
98    pub fn method(&self) -> &String {
99        &self.method
100    }
101
102    pub fn id(&self) -> &String {
103        &self.id
104    }
105}
106
107#[derive(Serialize, Deserialize)]
108struct ErrorValue {
109    code: i64,
110    message: String,
111}
112
113impl ErrorValue {
114    fn new(code: i64, message: String) -> Self {
115        ErrorValue { code, message }
116    }
117}
118
119#[derive(Serialize, Deserialize)]
120struct ErrorOnlyResponse {
121    jsonrpc: String,
122    error: ErrorValue,
123}
124
125#[derive(Serialize, Deserialize)]
126struct ErrorResponse {
127    jsonrpc: String,
128    method: String,
129    id: String,
130    error: ErrorValue,
131}
132
133impl ErrorOnlyResponse {
134    fn new(error: ErrorValue) -> Self {
135        let jsonrpc = "2.0".into();
136        ErrorOnlyResponse { jsonrpc, error }
137    }
138}
139
140impl ErrorResponse {
141    fn new(method: String, id: String, error: ErrorValue) -> Self {
142        let jsonrpc = "2.0".into();
143        ErrorResponse {
144            jsonrpc,
145            method,
146            id,
147            error,
148        }
149    }
150}
151
152// (String>, String) => method, id
153#[derive(Debug, Clone)]
154pub enum Error {
155    ParseError(Option<(String, String)>),
156    MethodNotFound(String, String),
157    InvalidRequest(String, String),
158    InvalidResponse(String, String),
159    ErrorResponse(String, String, i64, String),
160}
161
162impl Error {
163    fn error_value(&self) -> ErrorValue {
164        match self {
165            Error::ParseError(_) => ErrorValue::new(-32700, "Parse error".into()),
166            Error::MethodNotFound(_, _) => ErrorValue::new(-32601, "Method not found".into()),
167            Error::InvalidRequest(_, _) => ErrorValue::new(-32600, "Invalid Request".into()),
168            Error::InvalidResponse(_, _) => ErrorValue::new(-32600, "Invalid Response".into()),
169            Error::ErrorResponse(_, _, code, message) => ErrorValue::new(*code, message.clone()),
170        }
171    }
172
173    pub fn deparse(&self) -> Bytes {
174        let body =
175            match self {
176                Error::ParseError(Some((method, id))) => serde_json::to_string(
177                    &ErrorResponse::new(method.clone(), id.clone(), self.error_value()),
178                )
179                .unwrap(),
180                Error::ParseError(None) => {
181                    serde_json::to_string(&ErrorOnlyResponse::new(self.error_value()))
182                        .map_err(|e| {
183                            println!("{:?}", e);
184                        })
185                        .unwrap()
186                }
187                Error::MethodNotFound(method, id)
188                | Error::InvalidRequest(method, id)
189                | Error::InvalidResponse(method, id) => serde_json::to_string(&ErrorResponse::new(
190                    method.clone(),
191                    id.clone(),
192                    self.error_value(),
193                ))
194                .unwrap(),
195                Error::ErrorResponse(method, id, _, _) => serde_json::to_string(
196                    &ErrorResponse::new(method.clone(), id.clone(), self.error_value()),
197                )
198                .unwrap(),
199            };
200
201        let body_bytes = body.as_bytes();
202
203        let mut headers = generate_response_headers(body_bytes.len());
204        headers.put(body_bytes);
205        headers.freeze()
206    }
207}