@@ -65,6 +65,7 @@ extern crate serde;
65
65
#[ cfg_attr( test, macro_use) ]
66
66
extern crate serde_json;
67
67
68
+ use futures:: Async ;
68
69
use futures:: future:: Future ;
69
70
use jsonrpc_core:: types:: { Id , MethodCall , Params , Version } ;
70
71
use serde_json:: Value as JsonValue ;
@@ -102,34 +103,95 @@ error_chain! {
102
103
}
103
104
}
104
105
105
- /// A `Future` trait object.
106
- pub type BoxFuture < T , E > = Box < Future < Item = T , Error = E > + Send > ;
107
106
108
107
/// A lazy RPC call `Future`. The actual call has not been sent when an instance of this type
109
108
/// is returned from a client generated by the macro in this crate. This is a `Future` that, when
110
109
/// 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 > > ) ;
112
111
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
+ {
114
118
/// Consume this RPC request and run it synchronously. This blocks until the RPC call is done,
115
119
/// then the result of the call is returned.
116
120
pub fn call ( self ) -> Result < T > {
117
- self . 0 . wait ( )
121
+ self . wait ( )
118
122
}
119
123
}
120
124
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
+ {
122
131
type Item = T ;
123
132
type Error = Error ;
124
133
125
134
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
+ }
127
141
}
128
142
}
129
143
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
+
130
189
/// Trait for types acting as a transport layer for the JSON-RPC 2.0 clients generated by the
131
190
/// `jsonrpc_client` macro.
132
191
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
+
133
195
/// The type of error that this transport emits if it fails.
134
196
type Error : :: std:: error:: Error + Send + ' static ;
135
197
@@ -139,7 +201,7 @@ pub trait Transport {
139
201
140
202
/// Sends the given data over the transport and returns a future that will complete with the
141
203
/// 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 ;
143
205
}
144
206
145
207
@@ -150,41 +212,25 @@ pub trait Transport {
150
212
/// # Not intended for direct use
151
213
/// This is being called from the client structs generated by the `jsonrpc_client` macro. This
152
214
/// 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 >
154
220
where
155
221
T : Transport ,
156
222
P : serde:: Serialize ,
157
223
R : serde:: de:: DeserializeOwned + Send + ' static ,
158
224
{
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) ;
166
227
let request_serialization_result = serialize_request ( id. clone ( ) , method. clone ( ) , params)
167
228
. chain_err ( || ErrorKind :: SerializeError ) ;
168
229
match request_serialization_result {
169
- Err ( e) => RpcRequest ( Box :: new ( futures :: future :: err ( e) ) ) ,
230
+ Err ( e) => RpcRequest ( Err ( Some ( e) ) ) ,
170
231
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) ) )
188
234
}
189
235
}
190
236
}
@@ -220,19 +266,22 @@ mod tests {
220
266
use super :: * ;
221
267
use std:: io;
222
268
269
+ pub type BoxFuture < T , E > = Box < Future < Item = T , Error = E > + Send > ;
270
+
223
271
/// A test transport that just echoes back a response containing the entire request as the
224
272
/// result.
225
273
#[ derive( Clone ) ]
226
274
struct EchoTransport ;
227
275
228
276
impl Transport for EchoTransport {
277
+ type Future = BoxFuture < Vec < u8 > , io:: Error > ;
229
278
type Error = io:: Error ;
230
279
231
280
fn get_next_id ( & mut self ) -> u64 {
232
281
1
233
282
}
234
283
235
- fn send ( & self , json_data : Vec < u8 > ) -> BoxFuture < Vec < u8 > , io :: Error > {
284
+ fn send ( & self , json_data : Vec < u8 > ) -> Self :: Future {
236
285
let json = json ! ( {
237
286
"jsonrpc" : "2.0" ,
238
287
"id" : 1 ,
@@ -247,13 +296,14 @@ mod tests {
247
296
struct ErrorTransport ;
248
297
249
298
impl Transport for ErrorTransport {
299
+ type Future = BoxFuture < Vec < u8 > , io:: Error > ;
250
300
type Error = io:: Error ;
251
301
252
302
fn get_next_id ( & mut self ) -> u64 {
253
303
1
254
304
}
255
305
256
- fn send ( & self , _json_data : Vec < u8 > ) -> BoxFuture < Vec < u8 > , io :: Error > {
306
+ fn send ( & self , _json_data : Vec < u8 > ) -> Self :: Future {
257
307
let json = json ! ( {
258
308
"jsonrpc" : "2.0" ,
259
309
"id" : 1 ,
0 commit comments