1use super::{helpers, Error};
2use alloc::string::{String, ToString};
3use core::{fmt, str::FromStr};
4use serde::{Deserialize, Serialize};
5use serde_json::{Number, Value};
6
7#[derive(Serialize, Deserialize, Debug, Clone)]
9pub struct Request {
10 pub jsonrpc: String,
12 pub id: Value,
14 pub method: String,
16
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub params: Option<Value>,
20}
21
22impl Request {
23 pub fn new<M>(method: M) -> Self
27 where
28 M: ToString,
29 {
30 #[cfg(feature = "uuid")]
31 let id = Value::String(uuid::Uuid::new_v4().to_string());
32
33 #[cfg(not(feature = "uuid"))]
34 let id = Value::Number(0.into());
35
36 Request {
37 id,
38 jsonrpc: "2.0".to_string(),
39 method: method.to_string(),
40 params: None,
41 }
42 }
43
44 pub fn with_id<I>(mut self, id: I) -> Self
46 where
47 I: Into<Number>,
48 {
49 self.id = Value::Number(id.into());
50 self
51 }
52
53 pub fn with_id_string<I>(mut self, id: I) -> Self
55 where
56 I: ToString,
57 {
58 self.id = Value::String(id.to_string());
59 self
60 }
61
62 pub fn with_params<P>(self, params: P) -> Result<Self, Error>
64 where
65 P: Serialize,
66 {
67 serde_json::to_value(params)
68 .map_err(|e| Error {
69 code: Error::PARSE_ERROR,
70 message: e.to_string(),
71 data: None,
72 })
73 .map(|params| self.with_params_value(params))
74 }
75
76 pub fn with_params_value(mut self, params: Value) -> Self {
78 self.params = Some(params);
79 self
80 }
81
82 pub fn prepare(&self) -> (Value, String) {
84 let id = self.id.clone();
85 let message = self.to_string();
86 (id, message)
87 }
88
89 pub fn parse(s: &str) -> Result<(Self, &str), Error> {
91 let (message, remainder) = helpers::get_content_length(s)?;
92 let request = Request::parse_json(message)?;
93 Ok((request, remainder))
94 }
95
96 pub fn parse_json(json: &str) -> Result<Self, Error> {
98 serde_json::from_str(json).map_err(|e| Error {
99 code: Error::INVALID_REQUEST,
100 message: e.to_string(),
101 data: Some(Value::String(json.to_string())),
102 })
103 }
104}
105
106impl FromStr for Request {
107 type Err = Error;
108
109 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 Self::parse(s).map(|(json, _)| json)
111 }
112}
113
114impl fmt::Display for Request {
115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116 serde_json::to_string(&self)
117 .map_err(|_| fmt::Error)
118 .and_then(|m| write!(f, "Content-Length: {}\r\n\r\n{}", m.len(), m))
119 }
120}
121
122#[cfg(feature = "std")]
123mod io {
124 use super::*;
125 use std::io::prelude::*;
126
127 impl Request {
128 pub fn try_from_reader<R>(reader: R) -> Result<(usize, Self), Error>
132 where
133 R: Read,
134 {
135 let (n, contents) = helpers::get_content_from_reader(reader)?;
136 let request = Request::parse_json(&contents)?;
137 Ok((n, request))
138 }
139
140 pub fn try_to_writer<W>(&self, mut writer: W) -> Result<usize, Error>
142 where
143 W: Write,
144 {
145 writer
146 .write(self.to_string().as_bytes())
147 .map_err(|e| Error {
148 code: Error::PARSE_ERROR,
149 message: e.to_string(),
150 data: serde_json::to_value(&self).ok(),
151 })
152 }
153 }
154}