1#![deny(missing_docs)]
57
58#[macro_use]
59pub extern crate error_chain;
60#[macro_use]
61extern crate futures;
62extern crate jsonrpc_core;
63#[macro_use]
64extern crate log;
65extern crate serde;
66#[cfg_attr(test, macro_use)]
67extern crate serde_json;
68
69use futures::future::Future;
70use futures::Async;
71use jsonrpc_core::types::{Id, MethodCall, Params, Version};
72use serde_json::Value as JsonValue;
73
74#[macro_use]
76mod macros;
77
78mod response;
80
81pub mod example;
83
84error_chain! {
85 errors {
86 TransportError {
88 description("Unable to send the JSON-RPC 2.0 request")
89 }
90 SerializeError {
92 description("Unable to serialize the method parameters")
93 }
94 ResponseError(msg: &'static str) {
96 description("Unable to deserialize the response into the desired type")
97 display("Unable to deserialize the response: {}", msg)
98 }
99 JsonRpcError(error: jsonrpc_core::Error) {
101 description("Method call returned JSON-RPC 2.0 error")
102 display("JSON-RPC 2.0 Error: {} ({})", error.code.description(), error.message)
103 }
104 }
105}
106
107
108pub struct RpcRequest<T, F>(::std::result::Result<InnerRpcRequest<T, F>, Option<Error>>);
112
113impl<T, E, F> RpcRequest<T, F>
114where
115 T: serde::de::DeserializeOwned + Send + 'static,
116 E: ::std::error::Error + Send + 'static,
117 F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
118{
119 pub fn call(self) -> Result<T> {
122 self.wait()
123 }
124}
125
126impl<T, E, F> Future for RpcRequest<T, F>
127where
128 T: serde::de::DeserializeOwned + Send + 'static,
129 E: ::std::error::Error + Send + 'static,
130 F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
131{
132 type Item = T;
133 type Error = Error;
134
135 fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
136 match self.0 {
137 Ok(ref mut inner) => inner.poll(),
138 Err(ref mut error_option) => Err(error_option
139 .take()
140 .expect("Cannot call RpcRequest poll twice when in error state")),
141 }
142 }
143}
144
145struct InnerRpcRequest<T, F> {
146 transport_future: F,
147 id: Id,
148 _marker: ::std::marker::PhantomData<T>,
149}
150
151impl<T, F> InnerRpcRequest<T, F> {
152 fn new(transport_future: F, id: Id) -> Self {
153 Self {
154 transport_future,
155 id,
156 _marker: ::std::marker::PhantomData,
157 }
158 }
159}
160
161impl<T, E, F> Future for InnerRpcRequest<T, F>
162where
163 T: serde::de::DeserializeOwned + Send + 'static,
164 E: ::std::error::Error + Send + 'static,
165 F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
166{
167 type Item = T;
168 type Error = Error;
169
170 fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
171 let response_raw = try_ready!(
172 self.transport_future
173 .poll()
174 .chain_err(|| ErrorKind::TransportError)
175 );
176 trace!(
177 "Deserializing {} byte response to request with id {:?}",
178 response_raw.len(),
179 self.id
180 );
181 response::parse(&response_raw, &self.id).map(|t| Async::Ready(t))
182 }
183}
184
185
186pub trait Transport {
189 type Future: Future<Item = Vec<u8>, Error = Self::Error> + Send + 'static;
191
192 type Error: ::std::error::Error + Send + 'static;
194
195 fn get_next_id(&mut self) -> u64;
198
199 fn send(&self, json_data: Vec<u8>) -> Self::Future;
202}
203
204
205pub fn call_method<T, P, R>(
213 transport: &mut T,
214 method: String,
215 params: P,
216) -> RpcRequest<R, T::Future>
217where
218 T: Transport,
219 P: serde::Serialize,
220 R: serde::de::DeserializeOwned + Send + 'static,
221{
222 let id = Id::Num(transport.get_next_id());
223 trace!("Serializing call to method \"{}\" with id {:?}", method, id);
224 let request_serialization_result =
225 serialize_request(id.clone(), method, params).chain_err(|| ErrorKind::SerializeError);
226 match request_serialization_result {
227 Err(e) => RpcRequest(Err(Some(e))),
228 Ok(request_raw) => {
229 let transport_future = transport.send(request_raw);
230 RpcRequest(Ok(InnerRpcRequest::new(transport_future, id)))
231 }
232 }
233}
234
235
236fn serialize_request<P>(
238 id: Id,
239 method: String,
240 params: P,
241) -> ::std::result::Result<Vec<u8>, serde_json::error::Error>
242where
243 P: serde::Serialize,
244{
245 let serialized_params = match serde_json::to_value(params)? {
246 JsonValue::Null => None,
247 JsonValue::Array(vec) => Some(Params::Array(vec)),
248 JsonValue::Object(obj) => Some(Params::Map(obj)),
249 value => Some(Params::Array(vec![value])),
250 };
251 let method_call = MethodCall {
252 jsonrpc: Some(Version::V2),
253 method,
254 params: serialized_params,
255 id,
256 };
257 serde_json::to_vec(&method_call)
258}
259
260
261#[cfg(test)]
262mod tests {
263 use super::*;
264 use std::io;
265
266 pub type BoxFuture<T, E> = Box<Future<Item = T, Error = E> + Send>;
267
268 #[derive(Clone)]
271 struct EchoTransport;
272
273 impl Transport for EchoTransport {
274 type Future = BoxFuture<Vec<u8>, io::Error>;
275 type Error = io::Error;
276
277 fn get_next_id(&mut self) -> u64 {
278 1
279 }
280
281 fn send(&self, json_data: Vec<u8>) -> Self::Future {
282 let json = json!({
283 "jsonrpc": "2.0",
284 "id": 1,
285 "result": serde_json::from_slice::<JsonValue>(&json_data).unwrap(),
286 });
287 Box::new(futures::future::ok(serde_json::to_vec(&json).unwrap()))
288 }
289 }
290
291 #[derive(Clone)]
293 struct InvalidRequestTransport;
294
295 impl Transport for InvalidRequestTransport {
296 type Future = BoxFuture<Vec<u8>, io::Error>;
297 type Error = io::Error;
298
299 fn get_next_id(&mut self) -> u64 {
300 1
301 }
302
303 fn send(&self, _json_data: Vec<u8>) -> Self::Future {
304 let json = json!({
305 "jsonrpc": "2.0",
306 "id": 1,
307 "error": {
308 "code": -32600,
309 "message": "This was an invalid request",
310 "data": [1, 2, 3],
311 }
312 });
313 Box::new(futures::future::ok(serde_json::to_vec(&json).unwrap()))
314 }
315 }
316
317 #[derive(Clone)]
319 struct ErrorTransport;
320
321 impl Transport for ErrorTransport {
322 type Future = BoxFuture<Vec<u8>, io::Error>;
323 type Error = io::Error;
324
325 fn get_next_id(&mut self) -> u64 {
326 1
327 }
328
329 fn send(&self, _json_data: Vec<u8>) -> Self::Future {
330 Box::new(futures::future::err(io::Error::new(
331 io::ErrorKind::Other,
332 "Internal transport error",
333 )))
334 }
335 }
336
337 jsonrpc_client!(pub struct TestRpcClient {
338 pub fn ping(&mut self, arg0: &str) -> RpcRequest<JsonValue>;
339 });
340
341 #[test]
342 fn echo() {
343 let mut client = TestRpcClient::new(EchoTransport);
344 let result = client.ping("Hello").call().unwrap();
345 if let JsonValue::Object(map) = result {
346 assert_eq!(Some(&JsonValue::from("2.0")), map.get("jsonrpc"));
347 assert_eq!(Some(&JsonValue::from(1)), map.get("id"));
348 assert_eq!(Some(&JsonValue::from("ping")), map.get("method"));
349 assert_eq!(Some(&JsonValue::from(vec!["Hello"])), map.get("params"));
350 assert_eq!(4, map.len());
351 } else {
352 panic!("Invalid response type: {:?}", result);
353 }
354 }
355
356 #[test]
357 fn invalid_request() {
358 let mut client = TestRpcClient::new(InvalidRequestTransport);
359 let error = client.ping("").call().unwrap_err();
360 if let &ErrorKind::JsonRpcError(ref json_error) = error.kind() {
361 use jsonrpc_core::ErrorCode;
362 assert_eq!(ErrorCode::InvalidRequest, json_error.code);
363 assert_eq!("This was an invalid request", json_error.message);
364 assert_eq!(Some(json!{[1, 2, 3]}), json_error.data);
365 } else {
366 panic!("Wrong error kind");
367 }
368 }
369
370 #[test]
371 fn transport_error() {
372 let mut client = TestRpcClient::new(ErrorTransport);
373 match client.ping("").call().unwrap_err().kind() {
374 &ErrorKind::TransportError => (),
375 _ => panic!("Wrong error kind"),
376 }
377 }
378}