@@ -206,21 +206,39 @@ impl RpcMethod {
206
206
}
207
207
208
208
fn generate_delegate_closure ( & self , is_subscribe : bool ) -> Result < proc_macro2:: TokenStream > {
209
- let mut param_types : Vec < _ > = self
209
+ let args = self
210
210
. trait_item
211
211
. sig
212
212
. inputs
213
213
. iter ( )
214
214
. cloned ( )
215
- . filter_map ( |arg| match arg {
216
- syn:: FnArg :: Typed ( ty) => Some ( * ty. ty ) ,
217
- _ => None ,
215
+ . filter_map ( |arg| {
216
+ if let syn:: FnArg :: Typed ( pat_type) = arg {
217
+ Some ( pat_type)
218
+ } else {
219
+ None
220
+ }
218
221
} )
219
- . collect ( ) ;
222
+ . enumerate ( ) ;
220
223
221
224
// special args are those which are not passed directly via rpc params: metadata, subscriber
222
- let special_args = Self :: special_args ( & param_types) ;
223
- param_types. retain ( |ty| !special_args. iter ( ) . any ( |( _, sty) | sty == ty) ) ;
225
+ let mut special_args = vec ! [ ] ;
226
+ let mut fn_args = vec ! [ ] ;
227
+
228
+ for ( i, arg) in args {
229
+ if let Some ( sarg) = Self :: special_arg ( i, arg. clone ( ) ) {
230
+ special_args. push ( sarg) ;
231
+ } else {
232
+ fn_args. push ( arg) ;
233
+ }
234
+ }
235
+
236
+ let special_args: Vec < _ > = special_args;
237
+ let fn_args: Vec < _ > = fn_args;
238
+
239
+ let param_types: Vec < _ > = fn_args. iter ( ) . cloned ( ) . map ( |arg| * arg. ty ) . collect ( ) ;
240
+ let arg_names: Vec < _ > = fn_args. iter ( ) . cloned ( ) . map ( |arg| * arg. pat ) . collect ( ) ;
241
+
224
242
if param_types. len ( ) > TUPLE_FIELD_NAMES . len ( ) {
225
243
return Err ( syn:: Error :: new_spanned (
226
244
& self . trait_item ,
@@ -232,28 +250,38 @@ impl RpcMethod {
232
250
. take ( param_types. len ( ) )
233
251
. map ( |name| ident ( name) )
234
252
. collect ( ) ) ;
235
- let param_types = & param_types;
236
- let parse_params = {
237
- // last arguments that are `Option`-s are optional 'trailing' arguments
238
- let trailing_args_num = param_types. iter ( ) . rev ( ) . take_while ( |t| is_option_type ( t) ) . count ( ) ;
239
-
240
- if trailing_args_num != 0 {
241
- self . params_with_trailing ( trailing_args_num, param_types, tuple_fields)
242
- } else if param_types. is_empty ( ) {
243
- quote ! { let params = params. expect_no_params( ) ; }
244
- } else if self . attr . params_style == Some ( ParamStyle :: Raw ) {
245
- quote ! { let params: _jsonrpc_core:: Result <_> = Ok ( ( params, ) ) ; }
246
- } else if self . attr . params_style == Some ( ParamStyle :: Positional ) {
247
- quote ! { let params = params. parse:: <( #( #param_types, ) * ) >( ) ; }
248
- } else {
249
- unimplemented ! ( "Server side named parameters are not implemented" ) ;
253
+ let parse_params = if param_types. is_empty ( ) {
254
+ quote ! { let params = params. expect_no_params( ) ; }
255
+ } else {
256
+ match self . attr . params_style . as_ref ( ) . unwrap ( ) {
257
+ ParamStyle :: Raw => quote ! { let params: _jsonrpc_core:: Result <_> = Ok ( ( params, ) ) ; } ,
258
+ ParamStyle :: Positional => {
259
+ // last arguments that are `Option`-s are optional 'trailing' arguments
260
+ let trailing_args_num = param_types. iter ( ) . rev ( ) . take_while ( |t| is_option_type ( t) ) . count ( ) ;
261
+ if trailing_args_num != 0 {
262
+ self . params_with_trailing ( trailing_args_num, & param_types, tuple_fields)
263
+ } else {
264
+ quote ! { let params = params. parse:: <( #( #param_types, ) * ) >( ) ; }
265
+ }
266
+ }
267
+ ParamStyle :: Named => quote ! {
268
+ #[ derive( serde:: Deserialize ) ]
269
+ #[ allow( non_camel_case_types) ]
270
+ struct __Params {
271
+ #(
272
+ #fn_args,
273
+ ) *
274
+ }
275
+ let params = params. parse:: <__Params>( )
276
+ . map( |__Params { #( #arg_names, ) * } | ( #( #arg_names, ) * ) ) ;
277
+ } ,
250
278
}
251
279
} ;
252
280
253
281
let method_ident = self . ident ( ) ;
254
282
let result = & self . trait_item . sig . output ;
255
- let extra_closure_args: & Vec < _ > = & special_args. iter ( ) . cloned ( ) . map ( |arg| arg. 0 ) . collect ( ) ;
256
- let extra_method_types: & Vec < _ > = & special_args. iter ( ) . cloned ( ) . map ( |arg| arg. 1 ) . collect ( ) ;
283
+ let extra_closure_args: Vec < _ > = special_args. iter ( ) . cloned ( ) . map ( |arg| * arg. pat ) . collect ( ) ;
284
+ let extra_method_types: Vec < _ > = special_args. iter ( ) . cloned ( ) . map ( |arg| * arg. ty ) . collect ( ) ;
257
285
258
286
let closure_args = quote ! { base, params, #( #extra_closure_args) , * } ;
259
287
let method_sig = quote ! { fn ( & Self , #( #extra_method_types, ) * #( #param_types) , * ) #result } ;
@@ -301,34 +329,35 @@ impl RpcMethod {
301
329
} )
302
330
}
303
331
304
- fn special_args ( param_types : & [ syn:: Type ] ) -> Vec < ( syn:: Ident , syn:: Type ) > {
305
- let meta_arg = param_types. first ( ) . and_then ( |ty| {
306
- if * ty == parse_quote ! ( Self :: Metadata ) {
307
- Some ( ty. clone ( ) )
308
- } else {
309
- None
310
- }
311
- } ) ;
312
- let subscriber_arg = param_types. get ( 1 ) . and_then ( |ty| {
313
- if let syn:: Type :: Path ( path) = ty {
314
- if path. path . segments . iter ( ) . any ( |s| s. ident == SUBSCRIBER_TYPE_IDENT ) {
315
- Some ( ty. clone ( ) )
316
- } else {
317
- None
332
+ fn special_arg ( index : usize , arg : syn:: PatType ) -> Option < syn:: PatType > {
333
+ match index {
334
+ 0 if arg. ty == parse_quote ! ( Self :: Metadata ) => Some ( syn:: PatType {
335
+ pat : Box :: new ( syn:: Pat :: Ident ( syn:: PatIdent {
336
+ attrs : vec ! [ ] ,
337
+ by_ref : None ,
338
+ mutability : None ,
339
+ ident : ident ( METADATA_CLOSURE_ARG ) ,
340
+ subpat : None ,
341
+ } ) ) ,
342
+ ..arg
343
+ } ) ,
344
+ 1 => match * arg. ty {
345
+ syn:: Type :: Path ( ref path) if path. path . segments . iter ( ) . any ( |s| s. ident == SUBSCRIBER_TYPE_IDENT ) => {
346
+ Some ( syn:: PatType {
347
+ pat : Box :: new ( syn:: Pat :: Ident ( syn:: PatIdent {
348
+ attrs : vec ! [ ] ,
349
+ by_ref : None ,
350
+ mutability : None ,
351
+ ident : ident ( SUBSCRIBER_CLOSURE_ARG ) ,
352
+ subpat : None ,
353
+ } ) ) ,
354
+ ..arg
355
+ } )
318
356
}
319
- } else {
320
- None
321
- }
322
- } ) ;
323
-
324
- let mut special_args = Vec :: new ( ) ;
325
- if let Some ( meta) = meta_arg {
326
- special_args. push ( ( ident ( METADATA_CLOSURE_ARG ) , meta) ) ;
327
- }
328
- if let Some ( subscriber) = subscriber_arg {
329
- special_args. push ( ( ident ( SUBSCRIBER_CLOSURE_ARG ) , subscriber) ) ;
357
+ _ => None ,
358
+ } ,
359
+ _ => None ,
330
360
}
331
- special_args
332
361
}
333
362
334
363
fn params_with_trailing (
0 commit comments