1use bytes::{BufMut, Bytes};
2use serde_derive::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::parse::{generate_request_headers, split_bytes};
6use crate::response::Error;
7use crate::types::Params;
8
9#[derive(Default, Debug, Clone, Serialize, Deserialize)]
10pub struct Request {
11 jsonrpc: String,
12 method: String,
13 id: String,
14 params: Params,
15 path: String,
16 host: String,
17}
18
19impl Request {
20 pub fn new(method: String, id: String, params: Params, path: String, host: String) -> Self {
21 let jsonrpc = "2.0".into();
22
23 Request {
24 jsonrpc,
25 method,
26 id,
27 params,
28 path,
29 host,
30 }
31 }
32
33 pub fn parse_from_json(value: Value) -> Result<Self, Error> {
34 let id = if let Some(id) = value.get("id") {
35 if id.is_number() {
36 id.as_u64().unwrap_or(0).to_string()
37 } else if id.is_string() {
38 id.as_str().unwrap().into()
39 } else {
40 " ".into()
41 }
42 } else {
43 " ".into()
44 };
45
46 if value.get("result").is_some() || value.get("error").is_some() {
48 return Err(Error::InvalidRequest("".into(), id));
49 }
50
51 if value.get("method").is_none() {
52 return Err(Error::MethodNotFound("".into(), id));
53 }
54
55 let method = value.get("method").unwrap().as_str().unwrap().into();
56
57 let params = if let Some(params) = value.get("params") {
58 params.clone()
59 } else {
60 Value::Null
61 };
62
63 let jsonrpc = "2.0".into();
64 let path = "/".into();
65 let host = "DEFAULT".into();
66
67 Ok(Request {
68 jsonrpc,
69 method,
70 id,
71 params,
72 path,
73 host,
74 })
75 }
76
77 pub fn parse(bytes: Bytes) -> Result<Self, Error> {
78 split_bytes(bytes).and_then(|value| Request::parse_from_json(value))
79 }
80
81 pub fn parse_from_json_bytes(bytes: Bytes) -> Result<Self, Error> {
82 serde_json::from_slice(&bytes[..])
83 .or(Err(Error::ParseError(None)))
84 .and_then(|value| Request::parse_from_json(value))
85 }
86
87 pub fn deparse(&self) -> Bytes {
88 let body = serde_json::to_string(&self).unwrap();
89
90 let body_bytes = body.as_bytes();
91
92 let mut headers =
93 generate_request_headers(self.path.clone(), self.host.clone(), body_bytes.len());
94 headers.put(body_bytes);
95 headers.freeze()
96 }
97
98 pub fn method(&self) -> &String {
99 &self.method
100 }
101
102 pub fn params(&self) -> &Params {
103 &self.params
104 }
105
106 pub fn id(&self) -> &String {
107 &self.id
108 }
109}