@@ -3,7 +3,7 @@ use std::collections::HashSet;
3
3
use quote:: quote;
4
4
use syn:: {
5
5
parse_quote, Token , punctuated:: Punctuated ,
6
- visit:: { self , Visit } ,
6
+ visit:: { self , Visit } , Result ,
7
7
} ;
8
8
use crate :: rpc_attr:: RpcMethodAttribute ;
9
9
@@ -20,7 +20,7 @@ pub enum MethodRegistration {
20
20
}
21
21
22
22
impl MethodRegistration {
23
- fn generate ( & self ) -> proc_macro2:: TokenStream {
23
+ fn generate ( & self ) -> Result < proc_macro2:: TokenStream > {
24
24
match self {
25
25
MethodRegistration :: Standard { method, has_metadata } => {
26
26
let rpc_name = & method. name ( ) ;
@@ -30,17 +30,17 @@ impl MethodRegistration {
30
30
} else {
31
31
quote ! ( add_method)
32
32
} ;
33
- let closure = method. generate_delegate_closure ( false ) ;
33
+ let closure = method. generate_delegate_closure ( false ) ? ;
34
34
let add_aliases = method. generate_add_aliases ( ) ;
35
35
36
- quote ! {
36
+ Ok ( quote ! {
37
37
del. #add_method( #rpc_name, #closure) ;
38
38
#add_aliases
39
- }
39
+ } )
40
40
} ,
41
41
MethodRegistration :: PubSub { name, subscribe, unsubscribe } => {
42
42
let sub_name = subscribe. name ( ) ;
43
- let sub_closure = subscribe. generate_delegate_closure ( true ) ;
43
+ let sub_closure = subscribe. generate_delegate_closure ( true ) ? ;
44
44
let sub_aliases = subscribe. generate_add_aliases ( ) ;
45
45
46
46
let unsub_name = unsubscribe. name ( ) ;
@@ -57,15 +57,15 @@ impl MethodRegistration {
57
57
} ;
58
58
let unsub_aliases = unsubscribe. generate_add_aliases ( ) ;
59
59
60
- quote ! {
60
+ Ok ( quote ! {
61
61
del. add_subscription(
62
62
#name,
63
63
( #sub_name, #sub_closure) ,
64
64
( #unsub_name, #unsub_closure) ,
65
65
) ;
66
66
#sub_aliases
67
67
#unsub_aliases
68
- }
68
+ } )
69
69
} ,
70
70
}
71
71
}
@@ -75,24 +75,25 @@ const SUBCRIBER_TYPE_IDENT: &str = "Subscriber";
75
75
const METADATA_CLOSURE_ARG : & str = "meta" ;
76
76
const SUBSCRIBER_CLOSURE_ARG : & str = "subscriber" ;
77
77
78
- const TUPLE_FIELD_NAMES : [ & str ; 26 ] = [ "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" ] ;
78
+ // tuples are limited to 16 fields: the maximum supported by `serde::Deserialize`
79
+ const TUPLE_FIELD_NAMES : [ & str ; 16 ] = [ "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" ] ;
79
80
80
81
pub fn generate_trait_item_method (
81
82
methods : & [ MethodRegistration ] ,
82
83
trait_item : & syn:: ItemTrait ,
83
84
has_metadata : bool ,
84
85
has_pubsub_methods : bool ,
85
- ) -> syn:: TraitItemMethod {
86
+ ) -> Result < syn:: TraitItemMethod > {
86
87
let io_delegate_type =
87
88
if has_pubsub_methods {
88
89
quote ! ( _jsonrpc_pubsub:: IoDelegate )
89
90
} else {
90
91
quote ! ( _jsonrpc_core:: IoDelegate )
91
92
} ;
92
- let add_methods: Vec < _ > = methods
93
+ let add_methods = methods
93
94
. iter ( )
94
95
. map ( MethodRegistration :: generate)
95
- . collect ( ) ;
96
+ . collect :: < Result < Vec < _ > > > ( ) ? ;
96
97
let to_delegate_body =
97
98
quote ! {
98
99
let mut del = #io_delegate_type:: new( self . into( ) ) ;
@@ -123,7 +124,7 @@ pub fn generate_trait_item_method(
123
124
. make_where_clause ( )
124
125
. predicates
125
126
. extend ( predicates) ;
126
- method
127
+ Ok ( method)
127
128
}
128
129
129
130
#[ derive( Clone ) ]
@@ -151,7 +152,7 @@ impl RpcMethod {
151
152
self . attr . is_pubsub ( )
152
153
}
153
154
154
- fn generate_delegate_closure ( & self , is_subscribe : bool ) -> proc_macro2:: TokenStream {
155
+ fn generate_delegate_closure ( & self , is_subscribe : bool ) -> Result < proc_macro2:: TokenStream > {
155
156
let mut param_types: Vec < _ > =
156
157
self . trait_item . sig . decl . inputs
157
158
. iter ( )
@@ -170,6 +171,12 @@ impl RpcMethod {
170
171
param_types. retain ( |ty|
171
172
special_args. iter ( ) . find ( |( _, sty) | sty == ty) . is_none ( ) ) ;
172
173
174
+ if param_types. len ( ) > TUPLE_FIELD_NAMES . len ( ) {
175
+ return Err ( syn:: Error :: new_spanned (
176
+ & self . trait_item ,
177
+ & format ! ( "Maximum supported number of params is {}" , TUPLE_FIELD_NAMES . len( ) )
178
+ ) ) ;
179
+ }
173
180
let tuple_fields : & Vec < _ > =
174
181
& ( TUPLE_FIELD_NAMES . iter ( ) . take ( param_types. len ( ) ) . map ( |name| ident ( name) ) . collect ( ) ) ;
175
182
let param_types = & param_types;
@@ -220,15 +227,15 @@ impl RpcMethod {
220
227
}
221
228
} ;
222
229
223
- quote ! {
230
+ Ok ( quote ! {
224
231
move |#closure_args| {
225
232
let method = & ( Self :: #method_ident as #method_sig) ;
226
233
#parse_params
227
234
match params {
228
235
#match_params
229
236
}
230
237
}
231
- }
238
+ } )
232
239
}
233
240
234
241
fn special_args ( param_types : & [ syn:: Type ] ) -> Vec < ( syn:: Ident , syn:: Type ) > {
0 commit comments