57
57
58
58
#[ macro_use]
59
59
extern crate error_chain;
60
+ #[ macro_use]
60
61
extern crate futures;
61
62
extern crate jsonrpc_core;
62
63
#[ macro_use]
@@ -65,6 +66,7 @@ extern crate serde;
65
66
#[ cfg_attr( test, macro_use) ]
66
67
extern crate serde_json;
67
68
69
+ use futures:: Async ;
68
70
use futures:: future:: Future ;
69
71
use jsonrpc_core:: types:: { Id , MethodCall , Params , Version } ;
70
72
use serde_json:: Value as JsonValue ;
@@ -102,34 +104,94 @@ error_chain! {
102
104
}
103
105
}
104
106
105
- /// A `Future` trait object.
106
- pub type BoxFuture < T , E > = Box < Future < Item = T , Error = E > + Send > ;
107
107
108
108
/// A lazy RPC call `Future`. The actual call has not been sent when an instance of this type
109
109
/// is returned from a client generated by the macro in this crate. This is a `Future` that, when
110
110
/// executed, performs the RPC call.
111
- pub struct RpcRequest < T > ( BoxFuture < T , Error > ) ;
111
+ pub struct RpcRequest < T , F > ( :: std :: result :: Result < InnerRpcRequest < T , F > , Option < Error > > ) ;
112
112
113
- impl < T > RpcRequest < T > {
113
+ impl < T , E , F > RpcRequest < T , F >
114
+ where
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
+ {
114
119
/// Consume this RPC request and run it synchronously. This blocks until the RPC call is done,
115
120
/// then the result of the call is returned.
116
121
pub fn call ( self ) -> Result < T > {
117
- self . 0 . wait ( )
122
+ self . wait ( )
118
123
}
119
124
}
120
125
121
- impl < T > Future for RpcRequest < T > {
126
+ impl < T , E , F > Future for RpcRequest < T , F >
127
+ where
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
+ {
122
132
type Item = T ;
123
133
type Error = Error ;
124
134
125
135
fn poll ( & mut self ) -> futures:: Poll < Self :: Item , Self :: Error > {
126
- self . 0 . poll ( )
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
+ }
127
142
}
128
143
}
129
144
145
+ struct InnerRpcRequest < T , F > {
146
+ transport_future : F ,
147
+ method : String ,
148
+ id : Id ,
149
+ _marker : :: std:: marker:: PhantomData < T > ,
150
+ }
151
+
152
+ impl < T , F > InnerRpcRequest < T , F > {
153
+ fn new ( transport_future : F , method : String , id : Id ) -> Self {
154
+ Self {
155
+ transport_future,
156
+ method,
157
+ id,
158
+ _marker : :: std:: marker:: PhantomData ,
159
+ }
160
+ }
161
+ }
162
+
163
+ impl < T , E , F > Future for InnerRpcRequest < T , F >
164
+ where
165
+ T : serde:: de:: DeserializeOwned + Send + ' static ,
166
+ E : :: std:: error:: Error + Send + ' static ,
167
+ F : Future < Item = Vec < u8 > , Error = E > + Send + ' static ,
168
+ {
169
+ type Item = T ;
170
+ type Error = Error ;
171
+
172
+ fn poll ( & mut self ) -> futures:: Poll < Self :: Item , Self :: Error > {
173
+ let response_raw = try_ready ! (
174
+ self . transport_future
175
+ . poll( )
176
+ . chain_err( || ErrorKind :: TransportError )
177
+ ) ;
178
+ trace ! (
179
+ "Deserializing {} byte response to method \" {}\" with id {:?}" ,
180
+ response_raw. len( ) ,
181
+ self . method,
182
+ self . id
183
+ ) ;
184
+ response:: parse ( & response_raw, & self . id ) . map ( |t| Async :: Ready ( t) )
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