1use alloc::string::String;
2use serde_json::json;
3
4use crate::{id_from_value, Error, ErrorCode, Result};
5
6#[repr(C)]
8#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
9pub struct Request {
10 jsonrpc: serde_json::Value,
11 id: Option<serde_json::Value>,
12 method: Option<serde_json::Value>,
13 params: Option<serde_json::Value>,
14}
15
16impl Request {
17 pub fn new() -> Self {
19 Self {
20 jsonrpc: json!(String::from("2.0")),
21 id: None,
22 method: None,
23 params: None,
24 }
25 }
26
27 pub fn new_null() -> Self {
29 Self {
30 jsonrpc: serde_json::Value::Null,
31 id: None,
32 method: None,
33 params: None,
34 }
35 }
36
37 pub fn jsonrpc(&self) -> Option<&str> {
41 self.jsonrpc.as_str()
42 }
43
44 pub fn id(&self) -> Option<u64> {
46 self.id.as_ref().map(|id| id_from_value(id).unwrap_or(0))
47 }
48
49 pub fn set_id(&mut self, id: u64) {
51 self.id = Some(json!(id));
52 }
53
54 pub fn with_id(mut self, id: u64) -> Self {
56 self.set_id(id);
57 self
58 }
59
60 pub fn method(&self) -> Option<&str> {
62 if let Some(m) = self.method.as_ref() {
63 m.as_str()
64 } else {
65 None
66 }
67 }
68
69 pub fn set_method(&mut self, method: &str) {
71 self.method = Some(json!(String::from(method)));
72 }
73
74 pub fn with_method(mut self, method: &str) -> Self {
76 self.set_method(method);
77 self
78 }
79
80 pub fn params_is_null(&self) -> bool {
82 self.params.is_none()
83 }
84
85 pub fn params<T: for<'de> serde::Deserialize<'de>>(&self) -> Result<T> {
89 if let Some(p) = self.params.as_ref() {
90 serde_json::from_value::<T>(p.clone()).map_err(|err| err.into())
91 } else {
92 Err(Error::new()
93 .with_code(ErrorCode::InvalidParams)
94 .with_message("null Params field"))
95 }
96 }
97
98 pub fn set_params<T: serde::Serialize>(&mut self, params: T) {
100 self.params = Some(json!(params));
101 }
102
103 pub fn with_params<T: serde::Serialize>(mut self, params: T) -> Self {
105 self.set_params(params);
106 self
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_request() -> Result<()> {
116 let exp_request =
117 "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test_method\",\"params\":null}";
118 let exp_params_request =
119 "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"test_params\",\"params\":[0,1,2,3]}";
120
121 let request = Request::new().with_id(1).with_method("test_method");
122
123 let params_request = Request::new()
124 .with_id(1)
125 .with_method("test_params")
126 .with_params([0, 1, 2, 3]);
127
128 assert_eq!(serde_json::to_string(&request)?.as_str(), exp_request);
129 assert_eq!(
130 serde_json::to_string(¶ms_request)?.as_str(),
131 exp_params_request
132 );
133
134 Ok(())
135 }
136}