1use serde;
10use serde::de::Visitor;
11use serde::de;
12use serde::Error;
13
14use serde_json;
15use serde_json::Value;
16
17use util::core::GResult;
18
19use jsonrpc_common::*;
20use json_util::*;
21
22pub fn check_jsonrpc_field<ERR, HELPER>(helper: &mut HELPER, json_obj: &mut JsonObject) -> Result<(), ERR>
25where
26 HELPER: JsonDeserializerHelper<ERR>,
27{
28 let jsonrpc = try!(helper.obtain_String(json_obj, "jsonrpc"));
29 if jsonrpc != "2.0" {
30 return Err(helper.new_error(r#"Property `jsonrpc` is not "2.0". "#))
31 };
32 Ok(())
33}
34
35#[derive(Debug, PartialEq, Clone)]
39pub struct Request {
40 pub id : Option<Id>,
43 pub method : String,
44 pub params : RequestParams,
45}
46
47impl Request {
48 pub fn new(id_number: u64, method: String, params: JsonObject) -> Request {
49 Request {
50 id : Some(Id::Number(id_number)),
51 method : method,
52 params : RequestParams::Object(params),
53 }
54 }
55}
56
57impl serde::Serialize for Request {
58 fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
59 where S: serde::Serializer
60 {
61 let elem_count = 4;
64 let mut state = try!(serializer.serialize_struct("Request", elem_count));
65 {
66 try!(serializer.serialize_struct_elt(&mut state, "jsonrpc", "2.0"));
67 if let Some(ref id) = self.id {
68 try!(serializer.serialize_struct_elt(&mut state, "id", id));
69 }
70 try!(serializer.serialize_struct_elt(&mut state, "method", &self.method));
71 try!(serializer.serialize_struct_elt(&mut state, "params", &self.params));
72 }
73 serializer.serialize_struct_end(state)
74 }
75}
76
77impl serde::Deserialize for Request {
78 fn deserialize<DE>(deserializer: &mut DE) -> Result<Self, DE::Error>
79 where DE: serde::Deserializer
80 {
81 let mut helper = SerdeJsonDeserializerHelper(deserializer);
82 let value = try!(Value::deserialize(helper.0));
83 let mut json_obj = try!(helper.as_Object(value));
84
85 try!(check_jsonrpc_field(&mut helper, &mut json_obj));
86
87 let id = json_obj.remove("id");
88 let id = try!(id.map_or(Ok(None), |value| serde_json::from_value(value).map_err(to_de_error)));
89 let method = try!(helper.obtain_String(&mut json_obj, "method"));
90 let params = try!(helper.obtain_Value(&mut json_obj, "params"));
91
92 let params = try!(to_jsonrpc_params(params).map_err(to_de_error));
93
94 Ok(Request { id : id, method : method, params : params })
95 }
96}
97
98
99#[derive(Debug, PartialEq, Clone)]
102pub enum RequestParams {
103 Object(JsonObject),
104 Array(Vec<Value>),
105 None,
106}
107
108impl RequestParams {
109 pub fn into_value(self) -> Value {
110 match self {
114 RequestParams::Object(object) => Value::Object(object),
115 RequestParams::Array(array) => Value::Array(array),
116 RequestParams::None => Value::Null,
117 }
118 }
119}
120
121impl serde::Serialize for RequestParams {
122 fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
123 where S: serde::Serializer
124 {
125 match *self {
126 RequestParams::Object(ref object) => object.serialize(serializer),
127 RequestParams::Array(ref array) => array.serialize(serializer),
128 RequestParams::None => serializer.serialize_none(),
129 }
130 }
131}
132
133pub fn to_jsonrpc_params(params: Value) -> GResult<RequestParams> {
134 match params {
135 Value::Object(object) => Ok(RequestParams::Object(object)),
136 Value::Array(array) => Ok(RequestParams::Array(array)),
137 Value::Null => Ok(RequestParams::None),
138 _ => Err("Property `params` not an Object, Array, or null.".into()),
139 }
140}
141
142impl serde::Deserialize for RequestParams {
143 fn deserialize<DE>(deserializer: &mut DE) -> Result<Self, DE::Error>
144 where DE: serde::Deserializer
145 {
146 deserializer.deserialize(RequestParams_DeserializeVisitor)
147 }
148}
149
150struct RequestParams_DeserializeVisitor;
151
152impl Visitor for RequestParams_DeserializeVisitor {
153 type Value = RequestParams;
154
155 fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
156 where E: Error,
157 {
158 Ok(RequestParams::None)
159 }
160
161 fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
162 where V: de::SeqVisitor,
163 {
164 let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
165 Ok(RequestParams::Array(values))
166 }
167
168 fn visit_map<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
169 where V: de::MapVisitor,
170 {
171 let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
172 Ok(RequestParams::Object(values))
173 }
174
175}
176
177
178
179#[cfg(test)]
180pub mod request_tests {
181
182 use super::*;
183
184 use util::tests::*;
185 use json_util::*;
186 use json_util::test_util::*;
187 use jsonrpc_common::*;
188
189 use serde_json::Value;
190 use serde_json::builder::ObjectBuilder;
191
192
193 #[test]
194 fn test__RequestParams() {
195
196 let sample_obj = unwrap_object_builder(ObjectBuilder::new().insert("xxx", 123));
197 let sample_string = Value::String("blah".into());
198
199 test_serde__RequestParams(RequestParams::Object(sample_obj.clone()));
200 test_serde__RequestParams(RequestParams::Array(vec![sample_string.clone(), sample_string]));
201 test_serde__RequestParams(RequestParams::None);
202 }
203
204 fn test_serde__RequestParams(params: RequestParams) {
205 let params_reser = test_serde(¶ms).0;
206 assert_equal(params_reser, params);
207 }
208
209 pub fn check_error(result: RequestError, expected: RequestError) {
210 assert_starts_with(&result.message, &expected.message);
211 assert_eq!(result, RequestError { message : result.message.clone(), .. expected });
212 }
213
214 #[test]
215 fn test_Request() {
216
217 let sample_params = unwrap_object_builder(ObjectBuilder::new()
218 .insert("param", "2.0")
219 .insert("foo", 123)
220 );
221
222 test_error_de::<Request>(
224 "{",
225 "EOF while"
226 );
227
228 test_error_de::<Request>(
229 "{ }",
230 "Property `jsonrpc` is missing.",
231 );
232
233 test_error_de::<Request>(
234 r#"{ "jsonrpc": "1.0" }"#,
235 r#"Property `jsonrpc` is not "2.0". "#,
236 );
237
238 test_error_de::<Request>(
239 r#"{ "jsonrpc": "2.0" }"#,
240 "Property `method` is missing.",
241 );
242 test_error_de::<Request>(
243 r#"{ "jsonrpc": "2.0", "method":null }"#,
244 "Value `null` is not a String.",
245 );
246
247 test_error_de::<Request>(
248 r#"{ "jsonrpc": "2.0", "method":"xxx" }"#,
249 "Property `params` is missing.",
250 );
251
252 assert_equal(
254 from_json(r#"{ "jsonrpc": "2.0", "method":"xxx", "params":null }"#),
255 Request { id : None, method : "xxx".into(), params : RequestParams::None, }
256 );
257
258 let request = Request::new(1, "myMethod".to_string(), sample_params.clone());
262 test_serde(&request);
263
264 let request = Request { id : None, method : "myMethod".to_string(), params : RequestParams::None, };
266 test_serde(&request);
267
268 let sample_array_params = RequestParams::Array(vec![]);
270 let request = Request { id : None, method : "myMethod".to_string(), params : sample_array_params, };
271 test_serde(&request);
272 }
273
274}