Skip to content

Commit 5ccea9a

Browse files
committed
Remove BoxFuture from core and replace with manual future impl
1 parent 177e232 commit 5ccea9a

File tree

4 files changed

+96
-44
lines changed

4 files changed

+96
-44
lines changed

core/src/lib.rs

Lines changed: 86 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ extern crate serde;
6565
#[cfg_attr(test, macro_use)]
6666
extern crate serde_json;
6767

68+
use futures::Async;
6869
use futures::future::Future;
6970
use jsonrpc_core::types::{Id, MethodCall, Params, Version};
7071
use serde_json::Value as JsonValue;
@@ -102,34 +103,95 @@ error_chain! {
102103
}
103104
}
104105

105-
/// A `Future` trait object.
106-
pub type BoxFuture<T, E> = Box<Future<Item = T, Error = E> + Send>;
107106

108107
/// A lazy RPC call `Future`. The actual call has not been sent when an instance of this type
109108
/// is returned from a client generated by the macro in this crate. This is a `Future` that, when
110109
/// executed, performs the RPC call.
111-
pub struct RpcRequest<T>(BoxFuture<T, Error>);
110+
pub struct RpcRequest<T, F>(::std::result::Result<InnerRpcRequest<T, F>, Option<Error>>);
112111

113-
impl<T> RpcRequest<T> {
112+
impl<T, E, F> RpcRequest<T, F>
113+
where
114+
T: serde::de::DeserializeOwned + Send + 'static,
115+
E: ::std::error::Error + Send + 'static,
116+
F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
117+
{
114118
/// Consume this RPC request and run it synchronously. This blocks until the RPC call is done,
115119
/// then the result of the call is returned.
116120
pub fn call(self) -> Result<T> {
117-
self.0.wait()
121+
self.wait()
118122
}
119123
}
120124

121-
impl<T> Future for RpcRequest<T> {
125+
impl<T, E, F> Future for RpcRequest<T, F>
126+
where
127+
T: serde::de::DeserializeOwned + Send + 'static,
128+
E: ::std::error::Error + Send + 'static,
129+
F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
130+
{
122131
type Item = T;
123132
type Error = Error;
124133

125134
fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
126-
self.0.poll()
135+
match self.0 {
136+
Ok(ref mut inner) => inner.poll(),
137+
Err(ref mut error_option) => Err(error_option
138+
.take()
139+
.expect("Cannot call RpcRequest poll twice when in error state")),
140+
}
127141
}
128142
}
129143

144+
struct InnerRpcRequest<T, F> {
145+
transport_future: F,
146+
method: String,
147+
id: Id,
148+
_marker: ::std::marker::PhantomData<T>,
149+
}
150+
151+
impl<T, F> InnerRpcRequest<T, F> {
152+
fn new(transport_future: F, method: String, id: Id) -> Self {
153+
Self {
154+
transport_future,
155+
method,
156+
id,
157+
_marker: ::std::marker::PhantomData,
158+
}
159+
}
160+
}
161+
162+
impl<T, E, F> Future for InnerRpcRequest<T, F>
163+
where
164+
T: serde::de::DeserializeOwned + Send + 'static,
165+
E: ::std::error::Error + Send + 'static,
166+
F: Future<Item = Vec<u8>, Error = E> + Send + 'static,
167+
{
168+
type Item = T;
169+
type Error = Error;
170+
171+
fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
172+
match self.transport_future.poll() {
173+
Ok(Async::NotReady) => Ok(Async::NotReady),
174+
Ok(Async::Ready(response_raw)) => {
175+
trace!(
176+
"Deserializing {} byte response to method \"{}\" with id {:?}",
177+
response_raw.len(),
178+
self.method,
179+
self.id
180+
);
181+
response::parse::<T>(&response_raw, &self.id).map(|t| Async::Ready(t))
182+
}
183+
Err(e) => Err(Error::with_chain(e, ErrorKind::TransportError)),
184+
}
185+
}
186+
}
187+
188+
130189
/// Trait for types acting as a transport layer for the JSON-RPC 2.0 clients generated by the
131190
/// `jsonrpc_client` macro.
132191
pub trait Transport {
192+
/// The future type this transport returns on send operations.
193+
type Future: Future<Item = Vec<u8>, Error = Self::Error> + Send + 'static;
194+
133195
/// The type of error that this transport emits if it fails.
134196
type Error: ::std::error::Error + Send + 'static;
135197

@@ -139,7 +201,7 @@ pub trait Transport {
139201

140202
/// Sends the given data over the transport and returns a future that will complete with the
141203
/// response to the request, or the transport specific error if something went wrong.
142-
fn send(&self, json_data: Vec<u8>) -> BoxFuture<Vec<u8>, Self::Error>;
204+
fn send(&self, json_data: Vec<u8>) -> Self::Future;
143205
}
144206

145207

@@ -150,41 +212,25 @@ pub trait Transport {
150212
/// # Not intended for direct use
151213
/// This is being called from the client structs generated by the `jsonrpc_client` macro. This
152214
/// function is not intended to be used directly, only the generated structs should call this.
153-
pub fn call_method<T, P, R>(transport: &mut T, method: String, params: P) -> RpcRequest<R>
215+
pub fn call_method<T, P, R>(
216+
transport: &mut T,
217+
method: String,
218+
params: P,
219+
) -> RpcRequest<R, T::Future>
154220
where
155221
T: Transport,
156222
P: serde::Serialize,
157223
R: serde::de::DeserializeOwned + Send + 'static,
158224
{
159-
let raw_id = transport.get_next_id();
160-
let id = Id::Num(raw_id);
161-
trace!(
162-
"Serializing call to method \"{}\" with id {}",
163-
method,
164-
raw_id
165-
);
225+
let id = Id::Num(transport.get_next_id());
226+
trace!("Serializing call to method \"{}\" with id {:?}", method, id);
166227
let request_serialization_result = serialize_request(id.clone(), method.clone(), params)
167228
.chain_err(|| ErrorKind::SerializeError);
168229
match request_serialization_result {
169-
Err(e) => RpcRequest(Box::new(futures::future::err(e))),
230+
Err(e) => RpcRequest(Err(Some(e))),
170231
Ok(request_raw) => {
171-
trace!(
172-
"Sending call to method \"{}\" with id {} to transport",
173-
method,
174-
raw_id
175-
);
176-
let future = transport
177-
.send(request_raw)
178-
.map_err(|e| Error::with_chain(e, ErrorKind::TransportError))
179-
.and_then(move |response_raw: Vec<u8>| {
180-
trace!(
181-
"Deserializing response to method \"{}\" with id {}",
182-
method,
183-
raw_id
184-
);
185-
response::parse::<R>(&response_raw, id)
186-
});
187-
RpcRequest(Box::new(future))
232+
let transport_future = transport.send(request_raw);
233+
RpcRequest(Ok(InnerRpcRequest::new(transport_future, method, id)))
188234
}
189235
}
190236
}
@@ -220,19 +266,22 @@ mod tests {
220266
use super::*;
221267
use std::io;
222268

269+
pub type BoxFuture<T, E> = Box<Future<Item = T, Error = E> + Send>;
270+
223271
/// A test transport that just echoes back a response containing the entire request as the
224272
/// result.
225273
#[derive(Clone)]
226274
struct EchoTransport;
227275

228276
impl Transport for EchoTransport {
277+
type Future = BoxFuture<Vec<u8>, io::Error>;
229278
type Error = io::Error;
230279

231280
fn get_next_id(&mut self) -> u64 {
232281
1
233282
}
234283

235-
fn send(&self, json_data: Vec<u8>) -> BoxFuture<Vec<u8>, io::Error> {
284+
fn send(&self, json_data: Vec<u8>) -> Self::Future {
236285
let json = json!({
237286
"jsonrpc": "2.0",
238287
"id": 1,
@@ -247,13 +296,14 @@ mod tests {
247296
struct ErrorTransport;
248297

249298
impl Transport for ErrorTransport {
299+
type Future = BoxFuture<Vec<u8>, io::Error>;
250300
type Error = io::Error;
251301

252302
fn get_next_id(&mut self) -> u64 {
253303
1
254304
}
255305

256-
fn send(&self, _json_data: Vec<u8>) -> BoxFuture<Vec<u8>, io::Error> {
306+
fn send(&self, _json_data: Vec<u8>) -> Self::Future {
257307
let json = json!({
258308
"jsonrpc": "2.0",
259309
"id": 1,

core/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ macro_rules! jsonrpc_client {
3232
$(
3333
$(#[$doc])*
3434
pub fn $method(&mut $selff $(, $arg_name: $arg_ty)*)
35-
-> $crate::RpcRequest<$return_ty>
35+
-> $crate::RpcRequest<$return_ty, T::Future>
3636
{
3737
let method = String::from(stringify!($method));
3838
let params = expand_params!($($arg_name,)*);

core/src/response.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use serde_json;
1313

1414
/// Parses a binary response into json, extracts the "result" field and tries to deserialize that
1515
/// to the desired type.
16-
pub fn parse<R>(response_raw: &[u8], expected_id: Id) -> Result<R>
16+
pub fn parse<R>(response_raw: &[u8], expected_id: &Id) -> Result<R>
1717
where
1818
R: serde::de::DeserializeOwned,
1919
{
@@ -24,7 +24,7 @@ where
2424
ErrorKind::ResponseError("Not JSON-RPC 2.0 compatible")
2525
);
2626
ensure!(
27-
response.id() == &expected_id,
27+
response.id() == expected_id,
2828
ErrorKind::ResponseError("Response id not equal to request id")
2929
);
3030
match response {
@@ -33,8 +33,6 @@ where
3333
serde_json::from_value::<R>(success.result)
3434
.chain_err(|| ErrorKind::ResponseError("Not valid for target type"))
3535
}
36-
Output::Failure(failure) => {
37-
Err(ErrorKind::JsonRpcError(failure.error).into())
38-
}
36+
Output::Failure(failure) => Err(ErrorKind::JsonRpcError(failure.error).into()),
3937
}
4038
}

http/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ extern crate native_tls;
8181
use futures::{future, Future, Stream};
8282
use futures::sync::{mpsc, oneshot};
8383
use hyper::{Client, Request, StatusCode, Uri};
84-
use jsonrpc_client_core::{BoxFuture, Transport};
84+
use jsonrpc_client_core::Transport;
8585
use std::str::FromStr;
8686
use std::sync::Arc;
8787
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -119,6 +119,9 @@ error_chain! {
119119
type CoreSender = mpsc::UnboundedSender<(Request, oneshot::Sender<Result<Vec<u8>>>)>;
120120
type CoreReceiver = mpsc::UnboundedReceiver<(Request, oneshot::Sender<Result<Vec<u8>>>)>;
121121

122+
/// Future type returned from `HttpTransport`.
123+
pub type HttpFuture<T, E> = Box<Future<Item = T, Error = E> + Send>;
124+
122125
/// The main struct of the HTTP transport implementation for
123126
/// [`jsonrpc_client_core`](../jsonrpc_client_core).
124127
///
@@ -336,13 +339,14 @@ impl HttpHandle {
336339
}
337340

338341
impl Transport for HttpHandle {
342+
type Future = HttpFuture<Vec<u8>, Error>;
339343
type Error = Error;
340344

341345
fn get_next_id(&mut self) -> u64 {
342346
self.id.fetch_add(1, Ordering::SeqCst) as u64
343347
}
344348

345-
fn send(&self, json_data: Vec<u8>) -> BoxFuture<Vec<u8>, Error> {
349+
fn send(&self, json_data: Vec<u8>) -> Self::Future {
346350
let request = self.create_request(json_data.clone());
347351
let (response_tx, response_rx) = oneshot::channel();
348352
let future = future::result(self.request_tx.unbounded_send((request, response_tx)))

0 commit comments

Comments
 (0)