@@ -6,6 +6,8 @@ extern crate quote;
6
6
extern crate syn;
7
7
8
8
use proc_macro:: TokenStream ;
9
+ use quote:: Tokens ;
10
+ use syn:: { Body , DeriveInput , VariantData } ;
9
11
10
12
#[ proc_macro_derive( NapiArgs ) ]
11
13
pub fn napi_args ( input : TokenStream ) -> TokenStream {
@@ -16,63 +18,18 @@ pub fn napi_args(input: TokenStream) -> TokenStream {
16
18
}
17
19
}
18
20
19
- fn impl_napi_args (
20
- ast : & syn:: DeriveInput ,
21
- ) -> Result < quote:: Tokens , & ' static str > {
21
+ fn impl_napi_args ( ast : & DeriveInput ) -> Result < Tokens , & ' static str > {
22
22
let name = & ast. ident ;
23
23
24
24
let variant_data = match ast. body {
25
- syn :: Body :: Struct ( ref data) => data,
25
+ Body :: Struct ( ref data) => data,
26
26
_ => return Err ( "NapiArgs can only be derived for structs" ) ,
27
27
} ;
28
28
29
- let ( init_list, count, imports) = match * variant_data {
30
- syn:: VariantData :: Struct ( ref fields) => {
31
- let inner = fields
32
- . iter ( )
33
- . enumerate ( )
34
- . map ( |( idx, field) | {
35
- let ident = field. clone ( ) . ident . unwrap ( ) ;
36
- quote ! {
37
- #ident: <_ as NapiValue >:: from_sys_checked(
38
- env,
39
- argv[ #idx] ,
40
- ) ?
41
- }
42
- } )
43
- . collect :: < Vec < _ > > ( ) ;
44
-
45
- let outer = quote ! {
46
- { #( #inner) , * }
47
- } ;
48
-
49
- let imports = quote ! {
50
- use :: napi:: NapiValue ;
51
- } ;
29
+ let count = args_count ( variant_data) ;
30
+ let ( init_list, imports) = gen_args_code ( variant_data) ;
52
31
53
- ( Some ( outer) , fields. len ( ) , imports)
54
- }
55
-
56
- syn:: VariantData :: Tuple ( ref fields) => {
57
- let inner = ( 0 ..fields. len ( ) )
58
- . map ( |idx| {
59
- quote ! {
60
- <_ as NapiValue >:: from_sys_checked( env, argv[ #idx] ) ?
61
- }
62
- } )
63
- . collect :: < Vec < _ > > ( ) ;
64
-
65
- let outer = quote ! {
66
- ( #( #inner) , * )
67
- } ;
68
-
69
- ( Some ( outer) , fields. len ( ) , quote ! { } )
70
- }
71
-
72
- syn:: VariantData :: Unit => ( None , 0 , quote ! { } ) ,
73
- } ;
74
-
75
- let construct = if let Some ( init_list) = init_list {
32
+ let initializer = if let Some ( init_list) = init_list {
76
33
quote ! { #name #init_list }
77
34
} else {
78
35
quote ! { #name }
@@ -81,7 +38,7 @@ fn impl_napi_args(
81
38
let ( gen_lifetime, ref_lifetime) = if count > 0 {
82
39
( quote ! { <' env> } , quote ! { ' env } )
83
40
} else {
84
- ( quote ! { } , quote ! { } )
41
+ ( quote ! { } , quote ! { } )
85
42
} ;
86
43
87
44
Ok ( quote ! {
@@ -120,8 +77,67 @@ fn impl_napi_args(
120
77
return Err ( NapiError :: type_error( env, & message) ) ;
121
78
}
122
79
123
- Ok ( #construct )
80
+ Ok ( #initializer )
124
81
}
125
82
}
126
83
} )
127
84
}
85
+
86
+ fn args_count ( variant_data : & VariantData ) -> usize {
87
+ match * variant_data {
88
+ VariantData :: Struct ( ref fields) | VariantData :: Tuple ( ref fields) => {
89
+ fields. len ( )
90
+ }
91
+ VariantData :: Unit => 0 ,
92
+ }
93
+ }
94
+
95
+ fn gen_args_code (
96
+ variant_data : & VariantData ,
97
+ ) -> ( Option < Tokens > , Option < Tokens > ) {
98
+ match * variant_data {
99
+ VariantData :: Struct ( ref fields) => {
100
+ let inner = fields
101
+ . iter ( )
102
+ . enumerate ( )
103
+ . map ( |( idx, field) | {
104
+ let ident = field. clone ( ) . ident . unwrap ( ) ;
105
+ quote ! {
106
+ #ident: <_ as NapiValue >:: from_sys_checked(
107
+ env,
108
+ argv[ #idx] ,
109
+ ) ?
110
+ }
111
+ } )
112
+ . collect :: < Vec < _ > > ( ) ;
113
+
114
+ let outer = quote ! {
115
+ { #( #inner) , * }
116
+ } ;
117
+
118
+ let imports = quote ! {
119
+ use :: napi:: NapiValue ;
120
+ } ;
121
+
122
+ ( Some ( outer) , Some ( imports) )
123
+ }
124
+
125
+ VariantData :: Tuple ( ref fields) => {
126
+ let inner = ( 0 ..fields. len ( ) )
127
+ . map ( |idx| {
128
+ quote ! {
129
+ <_ as NapiValue >:: from_sys_checked( env, argv[ #idx] ) ?
130
+ }
131
+ } )
132
+ . collect :: < Vec < _ > > ( ) ;
133
+
134
+ let outer = quote ! {
135
+ ( #( #inner) , * )
136
+ } ;
137
+
138
+ ( Some ( outer) , None )
139
+ }
140
+
141
+ VariantData :: Unit => ( None , None ) ,
142
+ }
143
+ }
0 commit comments